POJ 3338 Matrix Multiplication(随机化算法)

来源:互联网 发布:js同源策略有哪些 编辑:程序博客网 时间:2024/04/28 05:10

Matrix Multiplication
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 18463 Accepted: 3978

Description

You are given three n × n matrices AB 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 AB and 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

21 02 35 10 85 110 26

Sample Output

YES

Hint

Multiple inputs will be tested. So O(n3) algorithm will get TLE.

Source

POJ Monthly--2007.08.05, qzc


题目大意:

    给三个比较大的矩形,判断前两个的乘积是不是第三个。


解题思路:

    题目的hint明确说明了O(n^3)的方法会TLE,我试了一下,即使加优化也确实是TLE了,O(n^2.7)的写法没试,估计也过不了。

    既然常规方法写不了,我们就可以用随机化算法来求解了。由矩阵乘法的性质可以得到:A*B*X==C*X <==> A*B==C 。如果我们令X向量是一个N阶列向量,并且先算B*X,就可以把复杂度降为O(N^2),但是这样并不是一定正确的,虽然正确率比较高。于是我们就可以重复多次随机生成X向量,这样的成功率就非常高了(概率的证明有点长,这里就不写了)。

    不知道为什么在POJ上提交G++是RE,C++是AC,在51node上是AC。


AC代码:

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <ctime>using namespace std;#define mem(a,b) memset((a),(b),sizeof(a))const int MAXN=500+3;int N,a[3][MAXN][MAXN],l[MAXN],ll[MAXN],r[MAXN],X[MAXN];int main(){    srand((int)time(NULL));    while(~scanf("%d",&N))    {        for(int i=0;i<3;++i)//输入开始的三个矩阵            for(int j=0;j<N;++j)                for(int k=0;k<N;++k)                    scanf("%d",&a[i][j][k]);        int times=10;//随机10次        bool ans=true;        while(times>0)        {            mem(l,0);            mem(ll,0);            mem(r,0);            for(int i=0;i<N;++i)//随机构造用来检测的矩阵X                X[i]=rand()%100;            for(int i=0;i<N;++i)//计算B*X                for(int j=0;j<N;++j)                    l[i]+=X[j]*a[1][i][j];            for(int i=0;i<N;++i)//计算A*(B*X)                for(int j=0;j<N;++j)                    ll[i]+=l[j]*a[0][i][j];            for(int i=0;i<N;++i)//计算C*X                for(int j=0;j<N;++j)                    r[i]+=X[j]*a[2][i][j];            bool ok=true;            for(int i=0;i<N;++i)                if(ll[i]!=r[i])                {                    ok=false;                    break;                }            if(!ok)            {                ans=false;                break;            }            --times;        }        puts(ans?"YES":"NO");    }        return 0;}


0 0
原创粉丝点击