[ACM] POJ 3318 Matrix Multiplication (随机化算法)

Matrix Multiplication

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 16118   Accepted: 3485

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

2
1 0
2 3
5 1
0 8
5 1
10 26

Sample Output

YES

Hint

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

Source

POJ Monthly--2007.08.05, qzc

解题思路:

题意为给定N*N的矩阵 A,B,C , 如果A*B=C,输出YES,否则输出NO。

第一次接触随机化算法,真的很奇妙。利用计算机随机给出符合题意的值,再根据题意关系计算是否出现矛盾,如果出现,则不成功。比如本题,就随机给出一个行数row,一个列数col, 那么必须有

for(int i=1;i<=n;i++)

temp+=A[row][i]*B[i][col];   temp==C[row][col] ; 

如果 出现不相等,那么肯定是不符合A*B=C的。但是这里随机的次数是个问题,开大了怕超时,开小了怕得不出正确答案,所以尽量比所有可能情况多一点。这种弊端会在下面第二种方法中解决。

百度百科说的很好:

随机化算法是这样一种算法,在算法中使用了随机函数,且随机函数的返回值直接或者间接的影响了算法的执行流程或执行结果。随机化算法基于随机方法,依赖于概率大小。

在我们的生活中,人们经常会去掷色子来看结果,投硬币来决定行动,这就牵涉到一个问题:随机。

这种算法看上去是凭着运气做事,其实,随机化算法是有一定的理论基础的,我们可以想象,在[1,10000]这个闭区间里,随机1000次,随机到2这个数的几率是多大(约为0.1),何况1000次的随机在计算机程序中仅仅是一眨眼的功夫。可以看出,随机化算法有着广阔的前景。只是由于随机化算法比较难于掌控,所以并不是很多人都接触过他,但肯定有很多人都听说过。

例一

下面,我们就随机化问题,举一个例子:

一个长度在4..10的字符串中,需要判定是否可以在字符串中删去若干字符,使得改变后字符串符合以下条件之一:

(1)AAAA;(2)AABB;(3)ABAB;(4)ABBA。

例如:长度为6字符串“POPKDK”,若删除其中的“O”,“D”两个字母,则原串变为:“PPKK”,符合条件(2)AABB。

分析:

这道题很容易想到一种算法:运用排列组合:枚举每4个字母,然后逐一判断。算法是可行的,但是如果需要题目中加上一句话:需要判断n个字符串,且n<=100000,那么这样的耗时是不能让人忍受的,因为在枚举的过程中,是非常浪费时间的。

①:这里是指信息学中要求算法的普遍运算时间为:1000ms)

所以这道题有可能可以借助于随机化算法,下面我们来算一下在10个字符中取4个字符一共有多少种取法:C(4,10)=210。那么很容易得知,随机化算法如果随机300次,能得到的结果基本上就正确了(概率为1-(209/210)^300,约为0.76),而随机时的时间消耗是O(1),只需要判断没有随机重复即可,判重的时间复杂度也为O(1),并且最多随机300次,这样就可以有效地得到答案,最大运算次数为:O(300n),这是在计算机的承受范围内(1000ms)的。

从这里就能看出,随机化算法是一个很好的概率算法,但是它并不能保证正确,而且它单独使用的情况很少,大部分是与其他的算法:例如贪心、搜索等配合起来运用。

例二

排序问题。快速排序是排序方法中较为便捷的方法之一,但是由于它极不稳定,最好的时候时间复杂度为O(n㏒n),这里的㏒是指以2为底的对数运算。最坏的时候能达到与普通排序方法一样的O(n^2)。

而制约快速排序的有两个:一是数据,越无序的数据,快排的速度越快;二是中间点的枚举。

因为两个制约条件都与随机有着不可分开的关系。

所以,在快速排序中加入随机化算法无疑是十分重要的。

运用在:

(1)数据读入时,随机排放数据位置。

(2)中间点的枚举进行多次随机化后决定。

这样就基本上将快速排序的时间复杂度维持在最好状态。

第一种方法代码:

#include <iostream>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
const int maxn=510;
int A[maxn][maxn];
int B[maxn][maxn];
int C[maxn][maxn];
int n;

void input(int c[maxn][maxn])
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        scanf("%d",&c[i][j]);
}

bool ok()
{
    int row,col;//随机行数,列数
    for(int k=1;k<=30000;k++)
    {
        row=rand()%n+1;
        col=rand()%n+1;
        int temp=0;
        for(int i=1;i<=n;i++)
            temp+=A[row][i]*B[i][col];
        if(temp!=C[row][col])
                return false;
    }
    return true;
}

int main()
{
    scanf("%d",&n);
    srand(time(NULL));
    input(A);
    input(B);
    input(C);
    if(ok())
        cout<<"YES"<<endl;
    else
        cout<<"NO"<<endl;

    return 0;
}

第二种方法:

左乘一个一行N列的向量
r[],  那么 肯定有  r*A*B=r*C 

代码:

#include <iostream>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int maxn=510;
int A[maxn][maxn];
int B[maxn][maxn];
int C[maxn][maxn];
int r[maxn];
int rA[maxn];
int rAB[maxn];
int rC[maxn];
int n;

void input(int c[maxn][maxn])
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        scanf("%d",&c[i][j]);
}

bool ok()
{
    for(int j=1;j<=n;j++)
        for(int i=1;i<=n;i++)
    {
        rA[j]+=r[i]*A[i][j];
        rC[j]+=r[i]*C[i][j];
    }
    for(int j=1;j<=n;j++)
        for(int i=1;i<=n;i++)
        rAB[j]+=rA[i]*B[i][j];

    for(int i=1;i<=n;i++)
        if(rAB[i]!=rC[i])
        return false;
    return true;
}

int main()
{
    scanf("%d",&n);
    srand(time(NULL));
    input(A);
    input(B);
    input(C);
    memset(rA,0,sizeof(rA));
    memset(rAB,0,sizeof(rAB));
    memset(rC,0,sizeof(rC));
    for(int i=1;i<=n;i++)
        r[i]=rand()%99+1;
    if(ok())
        cout<<"YES"<<endl;
    else
        cout<<"NO"<<endl;
    return 0;
}

[ACM] POJ 3318 Matrix Multiplication (随机化算法)

时间: 2024-10-10 05:48:14

[ACM] POJ 3318 Matrix Multiplication (随机化算法)的相关文章

POJ 3318 Matrix Multiplication(随机化算法)

给你三个矩阵A,B,C.让你判断A*B是否等于C. 随机一组数据,然后判断乘以A,B之后是否与乘C之后相等. 很扯淡的啊,感觉这种算法不严谨啊... Matrix Multiplication Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16255   Accepted: 3515 Description You are given three n × n matrices A, B and C. Does the e

poj 3318 Matrix Multiplication

http://poj.org/problem?id=3318 矩阵A*矩阵B是否等于矩阵C 1 #include <cstdio> 2 #include <cstring> 3 #include <time.h> 4 #include <algorithm> 5 #define maxn 1010 6 using namespace std; 7 8 int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],d[maxn];

POJ 3318 Matrix Multiplication(矩阵乘法)

题目链接 题意 : 给你三个n维矩阵,让你判断A*B是否等于C. 思路 :优化将二维转化成一维的.随机生成一个一维向量d,使得A*(B*d)=C*d,多次生成多次测试即可使错误概率大大减小. 1 //3318 2 #include <stdio.h> 3 #include <string.h> 4 #include <time.h> 5 #include <stdlib.h> 6 #include <iostream> 7 8 using nam

POJ 题目3318 Matrix Multiplication(快速判断矩阵乘是否正确)

Matrix Multiplication Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17132   Accepted: 3732 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 posit

POJ3318--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 descript

[ACM] POJ 3233 Matrix Power Series (求矩阵A+A^2+A^3...+A^k,二分求和)

Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 15417   Accepted: 6602 Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + - + Ak. Input The input contains exactly one test cas

ACM: POJ 3660 Cow Contest - Floyd算法

链接 Cow Contest Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Eac

[ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)

The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4158   Accepted: 1777 Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receivesN orders for toys. The man

[ACM] POJ 2947 Widget Factory (高斯消元)

Widget Factory Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 4436   Accepted: 1502 Description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to