题目大意:给定矩阵A,B,C,问A*B是否等于C。
解题报告:n最大有500,普通矩阵乘法复杂度是n^3,显然会超。
这题的解决办法也多了。首先就用n^3算法。稍作优化,即判断A矩阵中A[i][j]是否等于0。等于则不用做乘法了。1700MS左右可以过。虽然时间很久,不过绝对是正确的算法。
然后可以用一个行向量左乘A*B和C。这样复杂度会降到n^2。其正确性也相对较高。
当然,还有看RP的随机化算法。随机检测300000次。这个真的很看RP,我交了几次都WA了。
贴代码:优化的n^3算法:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int a[500][500];
int b[500][500];
int c[500][500];
int main()
{
int n;
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 k=0;k<n;k++)
c[i][k]-=a[i][j]*b[j][k];
bool flag=true;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(c[i][j])
{
flag=false;
i=j=n;
}
puts(flag?"YES":"NO");
}
左乘行向量:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>
#include <algorithm>
using namespace std;
int a[500][500];
int b[500][500];
int c[500][500];
int x[500];
int y[500];
int z[500];
int main()
{
srand(unsigned(time(0)));
int n;
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++)
x[i]=rand()%10;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
y[i]+=x[j]*a[j][i];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
z[i]+=y[j]*b[j][i];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
z[i]-=x[j]*c[j][i];
bool flag=true;
for(int i=0;i<n;i++) if(z[i])
{
flag=false;
break;
}
puts(flag?"YES":"NO");
}
6W随机化:(得看RP了)
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
using namespace std;
int a[500][500];
int b[500][500];
int c[500][500];
int main()
{
srand(unsigned(time(0)));
int n;
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]);
bool flag=true;
int t=60000;
while(t--)
{
int x=rand()%n;
int y=rand()%n;
int temp=0;
for(int i=0;i<n;i++)
temp+=a[x][i]*b[i][y];
if(c[x][y]!=temp)
{
flag=false;
break;
}
}
puts(flag?"YES":"NO");
}