BZOJ 1142 POI2009 Tab Hash

题目大意:给定两个矩阵,保证矩阵内所有元素都不相同,求第一个矩阵通过交换行和列是否可以得到第二个矩阵

令每一行的哈希值为这一行的元素排序后的RK哈希值,将行按照哈希值排序

然后把每一列按顺序哈希一下,排个序取RK哈希作为整个矩阵的哈希值

判断两个矩阵的哈希值是否相等即可

由于矩阵中元素不重复所以可以保证第一步的哈希值不会出现重复

然后。。。我都写完了它告诉我是2B题????

算了反正POI官网上能过就是了= =

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1010
#define BASE1 999911657
#define BASE2 999911659
using namespace std;
int m,n;
int a[M][M],b[M][M];
unsigned long long Calculate()
{
	int i,j;
	static pair<unsigned long long,int> c[M];
	for(i=1;i<=m;i++)
	{
		static int temp[M];
		for(j=1;j<=n;j++)
		{
			scanf("%d",&a[i][j]);
			temp[j]=a[i][j];
		}
		sort(temp+1,temp+n+1);
		c[i]=make_pair(0ull,i);
		for(j=1;j<=n;j++)
			(c[i].first*=BASE1)+=temp[j];
	}
	sort(c+1,c+m+1);
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
			b[i][j]=a[c[i].second][j];
	static unsigned long long d[M];
	for(j=1;j<=n;j++)
	{
		d[j]=0;
		for(i=1;i<=m;i++)
			(d[j]*=BASE1)+=b[i][j];
	}
	sort(d+1,d+n+1);
	unsigned long long re=0;
	for(i=1;i<=n;i++)
		(re*=BASE2)+=d[i];
	return re;
}
int main()
{
	int T;
	for(cin>>T;T;T--)
	{
		cin>>m>>n;
		unsigned long long hash1=Calculate();
		unsigned long long hash2=Calculate();
		puts(hash1==hash2?"TAK":"NIE");
	}
	return 0;
}


你可能感兴趣的:(hash,bzoj,BZOJ1142)