POJ 3318 Matrix Multiplication

Description

You are given three n × n matrices A, B 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 A, B and C 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(n 3) algorithm will get TLE.
设v是一个随机生成的n行1列的矩阵,取值范围为0~1
由A×B=C可得:
A×B×v=C×v
假如A×B!=C,那么有:(A×B-C)×v!=0
因为和只有1列的矩阵相乘都是O(n^2),且结果为n×1的矩阵,所以时间上是可以的
但是本身A×B×v=C×v不能推出A×B=C,但A×B×v!=C×v一定能推出A×B!=C
如:1 2 3  1       3 1 2  1    6
  3 2 1×1   =  1 2 3×1 = 6
  2 1 3  1       2 3 1  1    6
所以该算法判断不成立是正确的,但判断成立是不确定的
但是只要不是“不成立”,就是“成立”,所以问题不大,所以可以多次判断来决定是否“成立”
而且假设算出的矩阵第i行不为0,那么可能v[i][1]=0,使得判断失误
所以至少有1/2的几率判断出“不成立”
要在原有算法上多次判定,大概60次就行,错误率为2-60
其实v的取值范围扩大和判断次数增加都能增加准确度,这里v用值0/1只是方便分析
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<ctime>
 7 using namespace std;
 8 int n,flag,a[501][501],b[501][501],c[501][501],A[501],B[501],C[501],v[501];
 9 int main()
10 {int i,j,k;
11   while (cin>>n)
12     {
13       flag=0;
14       for (i=1;i<=n;i++)
15     {
16       for (j=1;j<=n;j++)
17         scanf("%d",&a[i][j]);
18     }
19       for (i=1;i<=n;i++)
20     {
21       for (j=1;j<=n;j++)
22         scanf("%d",&b[i][j]);
23     }
24       for (i=1;i<=n;i++)
25     {
26       for (j=1;j<=n;j++)
27         scanf("%d",&c[i][j]);
28     }
29       srand(time(0));
30       for (k=1;k<=60;k++)
31     {
32       for (i=1;i<=n;i++)
33         v[i]=rand()%2;
34       for (i=1;i<=n;i++)
35         {
36           B[i]=0;
37           for (j=1;j<=n;j++)
38         B[i]+=b[i][j]*v[j];
39         }
40       for (i=1;i<=n;i++)
41         {
42           C[i]=0;
43           for (j=1;j<=n;j++)
44         C[i]+=c[i][j]*v[j];
45         }
46       for (i=1;i<=n;i++)
47         {
48           A[i]=0;
49           for (j=1;j<=n;j++)
50         A[i]+=a[i][j]*B[j];
51         }
52       for (i=1;i<=n;i++)
53         if (A[i]!=C[i])
54           {
55         flag=1;
56         break;
57           }
58       if (flag) break;
59     }
60       if (flag) printf("NO\n");
61       else printf("YES\n");
62     }
63 }

 

转载于:https://www.cnblogs.com/Y-E-T-I/p/8310718.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值