1. 程式人生 > >BZOJ 1142 POI2009 Tab Hash

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;
}