您的位置:首页 > 其它

CSUOJ 1849 Comparing answers 哈希,hash,计算技巧

2017-03-25 23:26 453 查看


Description

In a place in Southwestern Europe, the name of which I do not wish to recall, not long ago there were n cities connected by unidirectional roads, with possibly more than one road connecting a city to another one,
or even to itself. As a homework assignment for your geography class, you need to calculate the number of paths of length exactly two that were between each pair of cities. However, you've been too busy celebrating the Spanish victory in the World Cup, so
now you are copying the answers from your friend. You would like to make sure his answers are correct before handing in your homework.


Input

  The input consists of several test cases, separated by single blank lines. Each test case begins with a line containing the integer n ( 1≤n≤10001≤n≤1000 ).
The following n lines contain n elements each, with element j of line i being the number of roads from city i to city j (a number between 0 and 10, inclusive). After that, there will be n lines. Each will contain n elements, with element j of line i being
the answer from your friend for the number of length-2 paths from city i to city j; it will be an integer between 0 and 100 000 inclusive.
  The test cases will finish with a line containing only the number zero (also preceded by a blank line).
  Note: Large input file , use fast I/O routines.


Output

  For each case, your program should output a line. The content of this line should be YES if your classmate's solution to the assignment is right, and NO otherwise.


Sample Input

3
2 0 1
1 0 3
1 1 0
5 1 2
5 3 1
3 0 4

3
2 0 1
1 0 3
1 1 0
5 1 2
5 3 2
3 0 4

0



Sample Output

YES
NO


以上的一大段说的是判断一个矩阵B是否是另外一个矩阵A的平方

因为要考虑B==A^2

直接的矩阵乘法的时间复杂度是n^3

考虑左右两边同时乘以一个n×1的行向量I,变成

BI==A^2*I

因为n×n的矩阵和行向量相乘的时间复杂度是n^2,成功~

当然这个行向量也不是随便取的,你要random,才能保证本来不相同的两个矩阵乘I后恰好相同了

按照dalao的说法是把一行给哈希成了行向量中的一个分量,我感觉也是有道理的

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctime>

using namespace std;
using ll=long long;

ll row[1010][2],arr1[1010][1010],arr2[1010][1010],n,tmp[1010];

inline bool judge(){
for(int i=0;i<n;++i)
if(row[i][0]!=row[i][1])
return false;
return true;
}

int main(){
ios_base::sync_with_stdio(false);
srand(time(0));
while(cin>>n&&n){

for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>arr1[i][j];

for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>arr2[i][j];

for(int i=0;i<n;++i)
tmp[i]=rand()%8953;

memset(row,0,sizeof row);
for(int i=0;i<n;++i)
for(int k=0;k<n;++k)
row[i][1]+=arr2[i][k]*tmp[k];

for(int i=0;i<n;++i)
for(int k=0;k<n;++k)
row[i][0]+=arr1[i][k]*tmp[k];
for(int i=0;i<n;++i)
tmp[i]=row[i][0],row[i][0]=0;
for(int i=0;i<n;++i)
for(int k=0;k<n;++k)
row[i][0]+=arr1[i][k]*tmp[k];

cout<<(judge()?"YES\n":"NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息