poj3318 Matrix Multiplication

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;
}

 

posted @ 2018-10-16 23:50  kafuuchino  阅读(283)  评论(2编辑  收藏  举报