POJ3318 Matrix Multiplication
原题地址:http://poj.org/problem?id=3318
题意:
给定 n x n 的矩阵 A,B,C,问 A * B = C 是否成立?
由于数据组数较低,所以 O(n^3)会TLE。
数据范围
A[i][j],B[i][j]<=100, C[i][j]<=10,000,000
题解:
因为O(n^3)会TLE所以不能直接矩阵乘法,因此,在这里随机生成一个n*1的矩阵r,如果 A * B = C,必然有 A (B r) =C * r
A,B,C,与r相乘都是O(n^2)的。这时只需比对A (B r) 与C * r,如果不同则A * B = C 肯定成立,相同则可能成立,我们只需要在时间允许的范围内尽可能的多次比对,来降低错误率。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<ctime>
using namespace std;
const int N=505;
int n,a[N][N],b[N][N],c[N][N],r[N],x[N],y[N];
bool check()
{
for(int i=1;i<=n;i++)
r[i]=rand()%97+1;
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
y[i]+=b[i][j]*r[j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
x[i]+=a[i][j]*y[j];
memset(y,0,sizeof(y));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
y[i]+=c[i][j]*r[j];
for(int i=1;i<=n;i++)
if(x[i]!=y[i]) return 0;
return 1;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
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=1;
bool flag=0;
for(;k<=60;k++)
if(!check())
{flag=1; break;}
if(flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}