题意:给出矩阵A[N,P],B[P,M],C[N,M],判断A*B是否等于C,如果不等,题目会保证只有一个位置是错的,要求输出这个位置以及它应该是什么。

题解:对于矩阵乘法判等的问题,若是直接模拟一般都会超时。我们可以借助向量,这道题就用随机两个向量X[1,N],Y[M,1],然后X*A*B=x[1,M],X*C=x[1,M],判断两个x是不是相同,同理判断A*B*Y与C*Y的y是不是相等,都相等那就是正确的,否则,看x的哪个不等,代表这第几列错了,y的代表着第几行错了,最后在直接算一下这一行这一列该等于什么就行了。

View Code
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdlib>
  5 #include<ctime>
  6 using namespace std;
  7 const int N=1005;
  8 long long X[N],Y[N],A[N][N],B[N][N],C[N][N],_X[N],_Y[N];
  9 long long x[N],y[N],_x[N],_y[N];
 10 int n,p,m,r,c;
 11 long long getval()
 12 {
 13     long long tp=0;
 14     for(int i=0;i<p;i++)
 15         tp+=A[r][i]*B[i][c];
 16     return tp;
 17 }
 18 int main()
 19 {
 20     while(scanf("%d%d%d",&n,&p,&m)!=EOF)
 21     {
 22         for(int i=0; i<n; i++)
 23             for(int j=0; j<p; j++)
 24                 scanf("%lld",&A[i][j]);
 25         for(int i=0; i<p; i++)
 26             for(int j=0; j<m; j++)
 27                 scanf("%lld",&B[i][j]);
 28         for(int i=0; i<n; i++)
 29             for(int j=0; j<m; j++)
 30                 scanf("%lld",&C[i][j]);
 31         ERROR:
 32         r=c=-1;
 33         bool flag=true;
 34         srand(clock());
 35         for(int i=0; i<n; i++)
 36             _X[i]=X[i]=rand()%10000;
 37         for(int i=0; i<m; i++)
 38             _Y[i]=Y[i]=rand()%10000;
 39         for(int i=0; i<p; i++)//X*A
 40         {
 41             long long tp=0;
 42             for(int j=0; j<n; j++)
 43                 tp+=X[j]*A[j][i];
 44             x[i]=tp;
 45         }
 46         memcpy(X,x,sizeof(x));
 47         for(int i=0; i<m; i++)//X*A*B
 48         {
 49             long long tp=0;
 50             for(int j=0; j<p; j++)
 51                 tp+=X[j]*B[j][i];
 52             x[i]=tp;
 53         }
 54         for(int i=0; i<m; i++)//X*C
 55         {
 56             long long tp=0;
 57             for(int j=0; j<n; j++)
 58                 tp+=_X[j]*C[j][i];
 59             _x[i]=tp;
 60             if(tp!=x[i])
 61             {
 62                 flag=false;
 63                 c=i;
 64             }
 65         }
 66         for(int i=0; i<p; i++)//B*Y
 67         {
 68             long long tp=0;
 69             for(int j=0; j<m; j++)
 70                 tp+=B[i][j]*Y[j];
 71             y[i]=tp;
 72         }
 73         memcpy(Y,y,sizeof(y));
 74         for(int i=0; i<n; i++)//A*B*Y
 75         {
 76             long long tp=0;
 77             for(int j=0; j<p; j++)
 78                 tp+=A[i][j]*Y[j];
 79             y[i]=tp;
 80         }
 81         for(int i=0; i<n; i++)//C*Y
 82         {
 83             long long tp=0;
 84             for(int j=0; j<m; j++)
 85                 tp+=C[i][j]*_Y[j];
 86             _y[i]=tp;
 87             if(tp!=y[i])
 88             {
 89                 flag=false;
 90                 r=i;
 91             }
 92         }
 93         if(flag)
 94             printf("Yes\n");
 95         else
 96         {
 97             if(r==-1||c==-1)
 98                 goto ERROR;
 99             else
100                 printf("No\n%d %d\n%lld\n",r+1,c+1,getval());
101         }
102     }
103     return 0;
104 }