标签:矩阵快速幂
input | output |
---|---|
2 0 7 15 30 |
Yes |
3 100 35 40 0 22 0 10 11 0 |
No |
题意:
输入A矩阵,问
,求出的B矩阵是否有0,有的话NO,没有YES。
做法:
矩阵快速幂,先算出 K等于n(n-1)次的A矩阵。复杂度 是 log(n^2)*(n^3)=10^4 ,然后k循环加到 n(n+1),每次把矩阵再乘个A,然后加到B里。复杂度是 n*n^3=10^6。所以妥妥的。因为只在乎有没有0,输入只有正数,矩阵里也只有乘法和加法。所以我把非零数改成了1,然后乘法用状压位运算优化到n^2。跑得稍微快点。
#include<stdio.h> #include<string.h> #define Matr 60 //矩阵大小,注意能小就小 矩阵从1开始 所以Matr 要+1 最大可以100 #define ll int struct mat//矩阵结构体,a表示内容,size大小 矩阵从1开始 但size不用加一 { ll a[Matr][Matr]; mat()//构造函数 { memset(a,0,sizeof(a)); } }; int Size; mat add(mat m1,mat m2) { for(int i=1;i<=Size;i++) { for(int j=1;j<=Size;j++) { if(m1.a[i][j]||m2.a[i][j]) m1.a[i][j]=1; } } return m1; } mat multi(mat m1,mat m2)//状压,位运算 { mat ans=mat(); __int64 mm1[60];//一行的 __int64 mm2[60];//一列的 for(int i=1;i<=Size;i++) { mm1[i]=0; for(int j=1;j<=Size;j++) { mm1[i]<<=1; if(m1.a[i][j]) mm1[i]|=1; } } for(int i=1;i<=Size;i++)//列 { mm2[i]=0; for(int j=1;j<=Size;j++)//行 { mm2[i]<<=1; if(m2.a[j][i]) mm2[i]|=1; } } for(int i=1;i<=Size;i++) { for(int j=1;j<=Size;j++) { if(mm1[i]&mm2[j]) ans.a[i][j]=1; } } /* for(int i=1;i<=Size;i++) for(int j=1;j<=Size;j++) if(m1.a[i][j])//稀疏矩阵优化 for(int k=1;k<=Size;k++) ans.a[i][k]=(ans.a[i][k]+m1.a[i][j]*m2.a[j][k]); //i行k列第j项 */ return ans; } mat quickmulti(mat m,ll n)//二分快速幂 { mat ans=mat(); int i; for(i=1;i<=Size;i++)ans.a[i][i]=1; while(n) { if(n&1)ans=multi(m,ans);//奇乘偶子乘 挺好记的. m=multi(m,m); n>>=1; } return ans; } void print(mat m)//输出矩阵信息,debug用 { int i,j; printf("%d\n",Size); for(i=1;i<=Size;i++) { for(j=1;j<=Size;j++) printf("%d ",m.a[i][j]); printf("\n"); } } int judge(mat m) { for(int i=1;i<=Size;i++) { for(int j=1;j<=Size;j++) { if(m.a[i][j]==0) return 0; } } return 1; } int main() { mat gouzao=mat(),chu=mat();//构造矩阵 初始矩阵 mat ans=mat(); cin>>Size; for(int i=1;i<=Size;i++) { for(int j=1;j<=Size;j++) { int tem; scanf("%d",&tem); if(tem) gouzao.a[i][j]=1; } } chu=quickmulti(gouzao,Size*(Size-1)-1); for(int i=Size*(Size-1);i<=Size*(Size+1);i++) { chu=multi(chu,gouzao); ans=add(ans,chu); } if(judge(ans))//mei 0 puts("Yes"); else puts("No"); return 0; }
URAL 1507 Difficult Decision 矩阵快速幂
标签:矩阵快速幂
原文地址:http://blog.csdn.net/u013532224/article/details/44698613