#include <stdio.h>
int main()
{
puts("转载请注明出处[vmurder]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/45688219");
}
首先我们发现无论如何变换,该在一行的还是会在一行,该在一列的还是会在一列。
拿行举例:我们交换行,在一行的一定还同一行,不在一行的一定还不在同一行;我们交换列,则一个元素的行标号不会被改变,行上的【(在/不在)同一行】这条性质一定不会改变。
然后这样我们扫两遍矩阵。
第一遍我们把每行内元素排序,然后再把矩阵的每一行排下序,
然后第二遍则把列内元素排序,再把每一列排序,然后再比较一遍。
这个做法存在一个坑,就是你怎么知道这样就能变换过去?完全是YY的嘛!
呃貌似不是坑。。。。
如果是“TAK”,我们把该在同一行的都搞到对应行(判断过肯定能的),然后这个时候每行的元素集合肯定是相同的。但是行内可能会有问题。
于是我们再暴力对某一行内元素交换位置使得两矩阵此行相同。因为同列的元素集合都一样,所以两矩阵其它的所有行的元素也都对应上了。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
using namespace std;
int n,m,a[N][N],b[N][N];
int s[N],t[N];
struct Eli
{
int X[N];
void keep(int n){sort(X+1,X+n+1);}
bool operator < (const Eli &V)const
{return X[1]<V.X[1];}
}A[N],B[N];
int main()
{
int i,j,g;
for(scanf("%d",&g);g--;)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&a[i][j]);
for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&b[i][j]);
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)A[i].X[j]=a[i][j];
A[i].keep(m);
}
sort(A+1,A+n+1);
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)B[i].X[j]=b[i][j];
B[i].keep(m);
}
sort(B+1,B+n+1);
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)if(A[i].X[j]!=B[i].X[j])break;
if(j<=m)break;
}
if(i<=n){puts("NIE");continue;}
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)A[i].X[j]=a[j][i];
A[i].keep(n);
}
sort(A+1,A+m+1);
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)B[i].X[j]=b[j][i];
B[i].keep(n);
}
sort(B+1,B+m+1);
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)if(A[i].X[j]!=B[i].X[j])break;
if(j<=n)break;
}
if(i<=m){puts("NIE");continue;}
puts("TAK");
}
return 0;
}
原文地址:http://blog.csdn.net/vmurder/article/details/45688219