poj3318 Matrix Multiplication
题意:给定$n*n(n<=500)$的矩阵$A,B,C$,如果$A*B==C$,输出“YES”,否则为“NO”;多组数据,$O(n^{3})$必T
我们可以随机生成一个神奇的列向量$v$,你可以把它看做n*1或1*n的矩阵,里面的元素随机为0或1
蓝后我们考察 $A*(B*v)$和$C*v$是否相等
灰常显然 $A*B!=C ==> A*(B*v)!=C*v$
那么我们每次判断有$\frac{1}{2}$的概率判错
于是我们多判几次
试60次时,判错率$=2^{-60}\approx10^{-20}$
end.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define re register using namespace std; template<typename T>T max(T &a,T &b){return a>b?a:b;} template<typename T>T min(T &a,T &b){return a<b?a:b;} #define N 501 int n,k,u,a[N][N],b[N][N],c[N][N],d[N],e[N],f[N]; int main(){ srand(19260817); while(scanf("%d",&n)!=EOF){ for(re int i=1;i<=n;++i) for(re int j=1;j<=n;++j) scanf("%d",&a[i][j]); for(re int i=1;i<=n;++i) for(re int j=1;j<=n;++j) scanf("%d",&b[i][j]); for(re int i=1;i<=n;++i) for(re int j=1;j<=n;++j) scanf("%d",&c[i][j]); for(k=1;k<=60;++k){ for(re int i=1;i<=n;++i) d[i]=rand()&1; for(re int i=1;i<=n;++i){ e[i]=0; for(re int j=1;j<=n;++j) e[i]+=c[i][j]*d[j]; } for(re int i=1;i<=n;++i){ f[i]=0; for(re int j=1;j<=n;++j) f[i]+=b[i][j]*d[j]; } for(re int i=1;i<=n;++i) d[i]=f[i]; for(re int i=1;i<=n;++i){ f[i]=0; for(re int j=1;j<=n;++j) f[i]+=a[i][j]*d[j]; } for(u=1;u<=n&&e[u]==f[u];++u); if(u<=n) break; }puts(k>60?"YES\n":"NO\n"); }return 0; }