POJ 3318 矩阵乘法 随机算法

已知:三个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;
}


阅读更多
换一批

没有更多推荐了,返回首页