已知:三个N×N矩阵A,B,C
求:判断A·B = C是否成立(O(n^3)的直接矩阵乘法会超时)
输入:第1行为矩阵阶数N,之后为A,B,C各自的矩阵元素,按行输入
输出:若等式成立,输出YES;否则输出NO
Sample Input:
2
1 0
2 3
5 1
0 8
5 1
10 26
Sample Output:
YES
思路:
第一种思路 拉斯维加斯算法 LV
进行一定量的随机测试,测试方法为:随机在A中选取第i行,在B中选取第j列,判断其乘积是否等于C中对应元素c[i][j]
该方法的缺点是:不能100%正确判断,因此为了提高判断准确率同时降低时间复杂度,因选取合适的随机测试数量
第二种思路 蒙特格罗算法 MC
随机建立一个N×1的矩阵R,若A·(B·R) = C·R,则A·B = C,而这一算法时间复杂度为O(n^2)
代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int n;
long a[510][510];
long b[510][510];
long c[510][510];
long r[510];
long br[510] = {0}; //b与r的乘积
long abr[510] = {0}; //a与br的乘积
long cr[510] = {0}; //c与r的乘积
scanf("%d", &n);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%ld", &a[i][j]);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%ld", &b[i][j]);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%ld", &c[i][j]);
srand((unsigned int)time(0)); //种子只用生成一次
for(int i = 0; i < n; i++)
r[i] = rand()%100;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
br[i] += b[i][j]*r[j];
cr[i] += c[i][j]*r[j];
}
}
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
abr[i] += a[i][j]*br[j];
int yes = 1;
for(int i = 0; i < n; i++){
if(abr[i] != cr[i]){
yes = 0;
break;
}
}
if(yes == 1) printf("YES\n");
else printf("NO\n");
return 0;
}