Gym - 101341I:Matrix God(随机算法)
题意:给出N,以及三个矩阵A,B,C,大小都为N*N。问是否满足A*B=C; N<1000;
思路:由于矩阵乘法的复杂度为O(N^3);而部分验证又不能保证结果正确。我们巧妙地利用矩阵乘法的结合律:使其变为1*N和N*N的矩阵乘法,使复杂度降低为O(N^2); 即随机构造矩阵X(1*N),Y(N*1),那么问题成为验证X*A*B*Y==X*C*Y?然后利用结合律即可验证。
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1010; const int Mod=1e9+7; int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn]; int r1[maxn],r2[maxn],x1[maxn],x2[maxn],yy1[maxn],ans1,ans2; int main() { int T=10,N,i,j; scanf("%d",&N); for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&a[i][j]); for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&b[i][j]); for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&c[i][j]); while(T--){ for(i=1;i<=N;i++) r1[i]=rand()%Mod; //1*N for(i=1;i<=N;i++) r2[i]=rand()%Mod; //N*1 for(i=1;i<=N;i++) x1[i]=x2[i]=yy1[i]=0; ans1=ans2=0; for(i=1;i<=N;i++) //1*N N*N N*N N*1=(1*N)*(N*1) for(j=1;j<=N;j++) (x1[i]+=(ll)r1[j]*a[j][i]%Mod)%=Mod; for(i=1;i<=N;i++) for(j=1;j<=N;j++) (x2[i]+=(ll)b[i][j]*r2[j]%Mod)%=Mod; for(i=1;i<=N;i++) (ans1+=(ll)x1[i]*x2[i]%Mod)%=Mod; for(i=1;i<=N;i++) //1*N N*N N*1 =(1*N)*(N*1) for(j=1;j<=N;j++) (yy1[i]+=(ll)r1[j]*c[j][i]%Mod)%=Mod; for(i=1;i<=N;i++) (ans2+=(ll)yy1[i]*r2[i]%Mod)%=Mod; if(ans1!=ans2){ puts("NO"); return 0; } } puts("YES"); return 0; }
It is your time to fight!