# POJ 3318 Matrix Multiplication【矩阵相乘——随机化检测】

POJ 3318 Matrix Multiplication【矩阵相乘——随机化检测】http://poj.org/problem?id=3318

Matrix Multiplication
 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 16709 Accepted: 3646

Description

You are given three n × n matrices AB and C. Does the equation A × B = C hold true?

Input

The first line of input contains a positive integer n (n ≤ 500) followed by the the three matrices AB and respectively. Each matrix's description is a block of n × n integers.

It guarantees that the elements of A and B are less than 100 in absolute value and elements of C are less than 10,000,000 in absolute value.

Output

Output "YES" if the equation holds true, otherwise "NO".

Sample Input

2
1 0
2 3
5 1
0 8
5 1
10 26


Sample Output

YES

Hint

Multiple inputs will be tested. So O(n3) algorithm will get TLE.

Source

[Submit]   [Go Back]   [Status]   [Discuss]

【题意】n*n的矩阵A，B，C；判断是否A*B=C成立。

【分析】随机化检测可优化到o（n^2）。

【方法一代码】

//Accepted	4860K	1782MS	C++	991B
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

int a[600][600], b[600][600], c[600][600], d[600][600];
int n;

int main()
{
while(~scanf("%d", &n))
{
for(int i=0; i<n; i++)  for(int j=0; j<n; j++)
scanf("%d", &a[i][j]);
for(int i=0; i<n; i++)  for(int j=0; j<n; j++)
scanf("%d", &b[i][j]);
for(int i=0; i<n; i++)  for(int j=0; j<n; j++)
scanf("%d", &c[i][j]);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
if(a[i][j]){
for(int r=0; r<n; r++)
d[i][r] += a[i][j] * b[j][r];
}
int flag = 0;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++)
if(c[i][j] != d[i][j]){ flag = 1;  break; }
if(flag) break;
}
if(flag) puts("NO");
else puts("YES");
}
return 0;
}


【方法二 随机化检测】

//Accepted	6168K	1063MS	C++	1809B
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<iomanip>
#include<limits.h>
#include<stdlib.h>
#include<fstream>
#include<sstream>
//BASIC
#include<ctype.h>
#include<time.h>
#include<assert.h>
#include<bitset>
#include<cassert>
#include<complex>
//OTHER
#include<algorithm>
#include<deque>
#include<functional>
#include<iterator>
#include<vector>
#include<list>
#include<map>
#include<memory>
#include<numeric>
#include<queue>
#include<set>
#include<stack>
#include<utility>
//STL
using namespace std;
int a[1020][1020],b[1020][1020],c[1020][1020],y[1020],temp1[1020],temp2[1020];
int n;
bool judge(int x[])
{
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
temp1[i] += b[i][j]*x[j];
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
temp2[i] += a[i][j]*temp1[j];//a*b
for(int i = 1;i <= n;i++)//clear
temp1[i] = 0;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
temp1[i] += c[i][j]*x[j];
for(int i = 1;i <= n;i++)
{
if(temp1[i]!=temp2[i])
return false;
}
return true;
}
int main()
{
while(scanf("%d",&n)==1)
{
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]);

srand(0);
for(int i = 1;i <= 100;i++)
for(int j = 1;j <= n;j++)
y[j] = rand()%19;
if(judge(y))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}