题目大意:
给定三个n∗nn*nn∗n的矩阵AAA,BBB,CCC,判断是否A∗B=CA*B=CA∗B=C。
其中n≤1000n≤1000n≤1000。
分析:
我们随机一个n∗1n*1n∗1的矩阵RRR,对于满足上述式子的一个答案,必然有A∗B∗R=C∗RA*B*R=C*RA∗B∗R=C∗R。
而A∗B∗R=A∗(B∗R)A*B*R=A*(B*R)A∗B∗R=A∗(B∗R),都可以在O(n2)O(n^2)O(n2)做出。
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstdlib>
#define LL long long
const int maxn=1001;
using namespace std;
int n;
int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn];
int rad[maxn],ans1[maxn],ans2[maxn],tmp[maxn];
bool check()
{
for (int i=1;i<=n;i++) rad[i]=rand()%1000;
for (int i=1;i<=n;i++)
{
tmp[i]=0;
for (int j=1;j<=n;j++) tmp[i]+=c[j][i]*rad[j];
}
for (int i=1;i<=n;i++) ans2[i]=tmp[i];
for (int i=1;i<=n;i++)
{
tmp[i]=0;
for (int j=1;j<=n;j++) tmp[i]+=b[j][i]*rad[j];
}
for (int i=1;i<=n;i++) ans1[i]=tmp[i];
for (int i=1;i<=n;i++)
{
tmp[i]=0;
for (int j=1;j<=n;j++) tmp[i]+=a[j][i]*ans1[j];
}
for (int i=1;i<=n;i++) ans1[i]=tmp[i];
int flag=1;
for (int i=1;i<=n;i++) if (ans1[i]!=ans2[i]) return 0;
return 1;
}
void solve()
{
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 flag=1;
for (int i=1;i<=20;i++) flag&=check();
if (flag) printf("Yes\n");
else printf("No\n");
}
int main()
{
srand((unsigned)time(0));
while (scanf("%d",&n)!=EOF) solve();
}