C++-POJ3213-PM3-[矩阵乘法]

已知矩阵乘法是n^3的,必然超时

故可以在需要验证的等式AB=C两边同时左乘D

一个1xN的任意的不含0矩阵

设E=DA,F=EB,G=DC,则此时只需验证F=G

当匹配到非法列J时,跳出n^2寻找行I即可

记录一下Ans,C[I,J]的正确值,然后就愉快地AC了

为了偷懒,我使用的矩阵是A~G连续编号的,所以可以放入数组,不喜勿喷!

 1 #include <cstdio>
 2 typedef long long ll;
 3 const int MAXN=1005;
 4 struct Matrix{ll a[MAXN][MAXN];}A[8];
 5 void Mul(int a,int b,int c,int n,int p,int m){
 6     for(int i=1;i<=n;i++)
 7         for(int j=1;j<=m;j++)
 8             for(int k=1;k<=p;k++)
 9                 A[a].a[i][j]+=A[b].a[i][k]*A[c].a[k][j];
10 }
11 int main(){
12     int N,P,M;
13     while(scanf("%d%d%d",&N,&P,&M)!=EOF){
14         for(int i=0;i<MAXN;i++)for(int j=0;j<MAXN;j++)for(int k=0;k<8;k++)A[k].a[i][j]=0;
15         for(int i=1;i<=N;i++)for(int j=1;j<=P;j++)scanf("%lld",&A[1].a[i][j]);
16         for(int i=1;i<=P;i++)for(int j=1;j<=M;j++)scanf("%lld",&A[2].a[i][j]);
17         for(int i=1;i<=N;i++)for(int j=1;j<=M;j++)scanf("%lld",&A[3].a[i][j]);
18         for(int i=1;i<=N;i++)A[4].a[1][i]=(i&1)?1:-1;//这里可以乱写,233 
19         Mul(5,4,1,1,N,P),Mul(6,5,2,1,P,M),Mul(7,4,3,1,N,M);
20         int flag=0,I,J;ll Ans;
21         for(int i=1;i<=M;i++)if(A[6].a[1][i]!=A[7].a[1][i]){J=i;flag=1;break;}
22         if(flag){
23             for(int i=1;i<=N;i++){
24                 ll ans=0;
25                 for(int k=1;k<=P;k++)ans+=A[1].a[i][k]*A[2].a[k][J];
26                 if(ans!=A[3].a[i][J]){Ans=ans,I=i;break;}
27             }
28             printf("No\n%d %d\n%lld\n",I,J,Ans);
29         }
30         else puts("Yes");
31     }
32     return 0;
33 }

猜你喜欢

转载自www.cnblogs.com/JasonCow/p/12361193.html
今日推荐