数学专题训练4
2014-03-02 21:19
169 查看
这次是矩阵与行列式
题目一:bzoj1013
我看到这题时反正没什么感觉。。。
其实对于球来说。。其上每一个点到球心的距离都是相等的。。。于是就可以根据这个来列方程
设球心为(x1,x2,...)对于点(a1,a2,...),(b1,b2,...) 有Σ(ai-xi)^2=Σ(bi-xi)^2
看起来很麻烦。。因为方程有二次项
但其实这个式子是可以打开的。。。打开后变成Σ2*(bi-ai)xi = Σbi^2-Σai^2 二次项被消掉了,直接就是线性方程(我当时居然觉得ai^2这些是二次项没消掉纠结了半天,真是太傻×了)
然后确定一个点出来。。其他所有点都与这个点一起建立一个线性方程,组成线性方程组。。。
然后直接高斯消元就搞定了...
题目二:LA3704
这个题嘛。。。线性递推关系。。。一看就是矩阵乘法优化
设 矩阵v[t+1]=A*v[t],然后v[k]就等于 A^k *v[0]
但是仔细分析下矩阵乘法优化后的复杂度为 O(n^3logk),还是T得比较爽
这里要用到一个性质:A这个矩阵是一个循环矩阵(下一行由上一行依次移动以为得到)
而两个循环矩阵的乘积依旧是循环矩阵 。。所以我们在求A^k时,只计算和保存第一行就行了。。。
所以求A^k这个过程的复杂度就变成了 O(n^2logk).
至于矩阵怎么设计。。。应该不是很难的问题,实在解决不了的话可以给我留言。。我在这几个月会几乎天天都会来的
题目三:Uva 10828
这道题有点高端。。期望+线性方程组
假设点i的期望执行次数为xi
那么xi=xa/da+xb/db+xc/dc+..(a,b,c为xi的前驱节点,di为点i的出度,意思就是:i点的期望执行次数=从a点走过来的概率*a点的期望执行次数+...)
例外是x1=xa/da+xb/db+xc/dc+..+1(因为他一开始会执行一次。。相当于有一个0号节点做前驱)
列出方程组然后消元。。。貌似解决了
但是没有。。。因为有的点不会被执行。。有的点会被无限执行(比如自环),在方程组中体现为多余方程或者矛盾方程
高斯消元有回带过程。。这里不知道的量就没法回带了
所以直接用高斯约当消元。。。不用回带
最后剩下的方程如果是矛盾的则说明所对应的这个变量为inf,如果是多余方程的话就是所对应的节点不会被执行(这句话是我自己的理解。。。没有太细想,可能不太对)
白书上是这么说的:当A[i][i]=A[i]
=0时 即方程为 xi*0=0时 xi为0 ,当A[i][i]=0&&A[i]
>0 即方程为xi*0=s(s>0)时xi为inf。。。除此因为有无穷大的变量而不能找出解的方程对应的xi也是无穷大(我认为是由于可以从 inf节点 走来。。。但好像不太解释得通,求大牛指导!)
题目四:Uva11542
这个我也比较晕。。。就说一句:异或方程组的消元过程进行几行 大概就是 确定了多少个未知数吧(说错了不要打我)
题目一:bzoj1013
我看到这题时反正没什么感觉。。。
其实对于球来说。。其上每一个点到球心的距离都是相等的。。。于是就可以根据这个来列方程
设球心为(x1,x2,...)对于点(a1,a2,...),(b1,b2,...) 有Σ(ai-xi)^2=Σ(bi-xi)^2
看起来很麻烦。。因为方程有二次项
但其实这个式子是可以打开的。。。打开后变成Σ2*(bi-ai)xi = Σbi^2-Σai^2 二次项被消掉了,直接就是线性方程(我当时居然觉得ai^2这些是二次项没消掉纠结了半天,真是太傻×了)
然后确定一个点出来。。其他所有点都与这个点一起建立一个线性方程,组成线性方程组。。。
然后直接高斯消元就搞定了...
#include<cstdlib> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #include<iostream> using namespace std; int n; double A[10+5][10+5]; double zb[10+5][10+5],fsum=0; void gauss() { for(int i=1;i<=n;i++) { int maxt=i; for(int j=i+1;j<=n;j++) { if(fabs(A[j][1])>fabs(A[maxt][1]))maxt=j; } if(maxt!=i)for(int j=1;j<=n+1;j++)swap(A[i][j],A[maxt][j]); for(int j=i+1;j<=n;j++) { for(int k=n+1;k>=i;k--)A[j][k]-=A[i][k]*A[j][i]/A[i][i]; } } for(int i=n;i>=1;i--) { for(int j=i+1;j<=n;j++)A[i][n+1]-=A[i][j]*A[j][n+1]; A[i][n+1]/=A[i][i]; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lf",&zb[0][i]); fsum=fsum+zb[0][i]*zb[0][i]; } for(int i=1;i<=n;i++) { double suma=0; for(int j=1;j<=n;j++) { scanf("%lf",&zb[i][j]); suma+=zb[i][j]*zb[i][j]; A[i][j]=2*(zb[i][j]-zb[0][j]); } A[i][n+1]=suma-fsum; } gauss(); for(int i=1;i<n;i++)printf("%.3f ",A[i][n+1]); printf("%.3f\n",A [n+1]); return 0; }
题目二:LA3704
这个题嘛。。。线性递推关系。。。一看就是矩阵乘法优化
设 矩阵v[t+1]=A*v[t],然后v[k]就等于 A^k *v[0]
但是仔细分析下矩阵乘法优化后的复杂度为 O(n^3logk),还是T得比较爽
这里要用到一个性质:A这个矩阵是一个循环矩阵(下一行由上一行依次移动以为得到)
而两个循环矩阵的乘积依旧是循环矩阵 。。所以我们在求A^k时,只计算和保存第一行就行了。。。
所以求A^k这个过程的复杂度就变成了 O(n^2logk).
至于矩阵怎么设计。。。应该不是很难的问题,实在解决不了的话可以给我留言。。我在这几个月会几乎天天都会来的
#include<cstdlib> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #include<iostream> using namespace std; int n,m,d,k; int M[500+10][1]; int ele[500+10]; int temp[500+10]; int temp2[500+10]; int temp4[500+10]; int temp3[500+10][1]; void mul2(int a[],int b[][1]) { memcpy(temp3,b,sizeof(temp3)); memset(b,0,sizeof(temp3)); for(int i=0;i<n;i++) { for(int k=0;k<n;k++)b[i][0]=(b[i][0]+((long long)a[((k-i)%n+n)%n]*temp3[k][0])%m)%m; } } void mul(int a[],int b[]) { memcpy(temp2,a,sizeof(temp2)); memcpy(temp4,b,sizeof(temp4)); memset(a,0,sizeof(temp)); for(int i=0;i<n;i++) { for(int k=0;k<n;k++)a[i]=(a[i]+((long long)temp2[k]*temp4[((i-k)%n+n)%n])%m)%m; } } void qpow(int x) { memcpy(temp,ele,sizeof(temp)); memset(ele,0,sizeof(ele)); ele[0]=1; while(x) { if(x&1)mul(ele,temp); mul(temp,temp); x>>=1; } } int main() { while(scanf("%d%d%d%d",&n,&m,&d,&k)!=EOF) { for(int i=0;i<n;i++) { scanf("%d",&M[i][0]); } for(int i=0;i<n;i++) { if(i-0<=d||n-i<=d)ele[i]=1; } qpow(k); mul2(ele,M); for(int i=0;i<n-1;i++)printf("%d ",M[i][0]); printf("%d\n",M[n-1][0]); memset(M,0,sizeof(M)); memset(temp,0,sizeof(temp)); memset(temp4,0,sizeof(temp4)); memset(temp2,0,sizeof(temp2)); memset(temp3,0,sizeof(temp3)); memset(ele,0,sizeof(ele)); } return 0; }
题目三:Uva 10828
这道题有点高端。。期望+线性方程组
假设点i的期望执行次数为xi
那么xi=xa/da+xb/db+xc/dc+..(a,b,c为xi的前驱节点,di为点i的出度,意思就是:i点的期望执行次数=从a点走过来的概率*a点的期望执行次数+...)
例外是x1=xa/da+xb/db+xc/dc+..+1(因为他一开始会执行一次。。相当于有一个0号节点做前驱)
列出方程组然后消元。。。貌似解决了
但是没有。。。因为有的点不会被执行。。有的点会被无限执行(比如自环),在方程组中体现为多余方程或者矛盾方程
高斯消元有回带过程。。这里不知道的量就没法回带了
所以直接用高斯约当消元。。。不用回带
最后剩下的方程如果是矛盾的则说明所对应的这个变量为inf,如果是多余方程的话就是所对应的节点不会被执行(这句话是我自己的理解。。。没有太细想,可能不太对)
白书上是这么说的:当A[i][i]=A[i]
=0时 即方程为 xi*0=0时 xi为0 ,当A[i][i]=0&&A[i]
>0 即方程为xi*0=s(s>0)时xi为inf。。。除此因为有无穷大的变量而不能找出解的方程对应的xi也是无穷大(我认为是由于可以从 inf节点 走来。。。但好像不太解释得通,求大牛指导!)
#include<cstdlib> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const double eps=1e-8; int n; bool w[100+10][100+10]; int du[100+10]; double A[100+10][100+10]; bool inf[100+10]; void gauss_jordan() { for(int i=1;i<=n;i++) { int maxt=i; for(int j=i+1;j<=n;j++) { if(fabs(A[j][i])>fabs(A[maxt][i]))maxt=j; } if(abs(A[maxt][i])<eps)continue; if(i!=maxt)for(int j=1;j<=n+1;j++)swap(A[i][j],A[maxt][j]); for(int j=1;j<=n;j++) { if(i!=j) { for(int k=n+1;k>=i;k--) { A[j][k]-=A[j][i]/A[i][i]*A[i][k]; } } } } } int main() { int cas=0; while(scanf("%d",&n)!=EOF) { if(n==0)break; memset(w,0,sizeof(w)); memset(du,0,sizeof(du)); memset(A,0,sizeof(A)); memset(inf,0,sizeof(inf)); cas++; int a,b; while(scanf("%d%d",&a,&b)!=EOF) { if(a==0&&b==0)break; w[a][b]=1; du[a]++; } A[1][n+1]=1; for(int i=1;i<=n;i++) { A[i][i]=1; for(int j=1;j<=n;j++) { if(w[j][i]) A[i][j]-=1.0/du[j]; } } gauss_jordan(); for(int i=n;i>=1;i--) { if(fabs(A[i][i])<eps&&fabs(A[i][n+1])>eps)inf[i]=true; for(int j=i+1;j<=n;j++) { if(fabs(A[i][j])>eps&&inf[j])inf[i]=true; } } printf("Case #%d:\n",cas); int q; scanf("%d",&q); for(int i=1;i<=q;i++) { int u; scanf("%d",&u); if(inf[u])printf("infinity\n"); else printf("%.3f\n",fabs(A[u][u])<eps?0.0:A[u][n+1]/A[u][u]); } } return 0; }
题目四:Uva11542
这个我也比较晕。。。就说一句:异或方程组的消元过程进行几行 大概就是 确定了多少个未知数吧(说错了不要打我)
相关文章推荐
- 数学专题训练3
- 数学专题训练2
- 训练指南——数学专题一的总结
- 暑假训练专题二 并查集的理解 优先队列
- 【【henuacm2016级暑期训练】动态规划专题 H】Greenhouse Effect
- [从头学数学] 第242节 线段求交 专题图叠合
- 【 【henuacm2016级暑期训练】动态规划专题 P】Animals
- 假期训练专题及模板——排序
- 算法竞赛入门经典训练指南第四章几何专题答案
- GDUT2017秋季训练(七)-Color (数学容斥)
- GEF专题训练(一) RCP工程的创建1
- 数学专题总结
- 【专题训练】医院设置[2] | 树的边、点都带权重心
- (数学专题)eqution 逆元+扩展欧几里得+组合数
- 数论专题训练
- 暑假训练4-数据结构专题
- 图论专题训练1-D(K步最短路,矩阵连乘)
- 数学简单专题
- 【【henuacm2016级暑期训练】动态规划专题 I】Gargari and Permutations
- 线段树专题#4_蒟蒻训练历程记录_HDU1698_ 延迟标记、区间更新