题意:
给出三个n*n的矩阵,问A*B=C时是否成立,要求算法复杂度降低到O(n^3)
分析:
直接乘的话显然复杂度不满足,那么可以构造一个n维列向量V,取随机数0和1,如果A*B=C成立的话,那么A*(B*V)=C*V也一定成立,但是如果A*B≠C成立的话,那么也可能满足A*(B*V)=C*V的情况成立,容易知道,满足该条件的概率是1/2,那么进行60次判定,误判的可能性将降低到2的-60次方。
#include<cstdio>
#include<algorithm>
#include<ctime>
#include<climits>
#include<cstdlib>
using namespace std;
const int maxn=500+10;
int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],v[maxn],f[maxn],g[maxn];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&b[i][j]);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&c[i][j]);
}
}
int k;
for(k=1;k<=60;k++){
for(int i=1;i<=n;i++){
v[i]=rand()%2;
}
for(int i=1;i<=n;i++){
g[i]=0;
for(int j=1;j<=n;j++){
g[i]+=c[i][j]*v[j];
}
}
for(int i=1;i<=n;i++){
f[i]=0;
for(int j=1;j<=n;j++){
f[i]+=b[i][j]*v[j];
}
}
for(int i=1;i<=n;i++){
v[i]=f[i];
}
for(int i=1;i<=n;i++){
f[i]=0;
for(int j=1;j<=n;j++){
f[i]+=a[i][j]*v[j];
}
}
int i;
for(i=1;i<=n;i++){
if(f[i]!=g[i]) break;
}
if(i<=n) break;
}
if(k<=60) printf("NO\n");
else printf("YES\n");
return 0;
}