bzoj 1142 [POI2009]Tab 最小表示
[POI2009]Tab
Time Limit: 40 Sec Memory Limit: 162 MBSubmit: 373 Solved: 167
[Submit][Status][Discuss]
Description
2个n*m矩阵,保证同一个矩阵中元素两两不同。问能否通过若干次交换两行或交换两列把第一个矩阵变成第二
个。
Input
第一行正整数T(1≤T≤10)表示数据组数.
每组数据包括:第一行nm(1≤n,m≤1000)2个n行m列的整数矩阵,
元素绝对值均在10^6以内
Output
每组数据输出“TAK”/“NIE”表示能/不能.
Sample Input
2
4 3
1 2 3
4 5 6
7 8 9
10 11 12
11 10 12
8 7 9
5 4 6
2 1 3
2 2
1 2
3 4
5 6
7 8
4 3
1 2 3
4 5 6
7 8 9
10 11 12
11 10 12
8 7 9
5 4 6
2 1 3
2 2
1 2
3 4
5 6
7 8
Sample Output
TAK
NIE
NIE
HINT
Source
题解:如果可以知道两个矩阵的最小表示就可以比较是否相同了,现将最小的数放到最左上角,因为每个数不同
然后,按照行的开头,再按第一行的各列来排序,就可以了,这样二维的位置,就已经被二维关键字排过了,是唯一的。
然后比较即可,时间复杂度貌似是n^3的,但是过了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 8 const int N=1005; 9 10 int a[N][N],b[N][N],n,m; 11 12 int read() 13 { 14 int x=0,f=1;char ch=getchar(); 15 while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 16 while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 17 return x*f; 18 } 19 20 void work1() 21 { 22 int x,y,mn=1e7; 23 for (int i=1;i<=n;i++) 24 for (int j=1;j<=m;j++) 25 if (a[i][j]<mn) mn=a[i][j],x=i,y=j; 26 if (x!=1) for (int i=1;i<=m;i++) swap(a[x][i],a[1][i]); 27 if (y!=1) for (int i=1;i<=n;i++) swap(a[i][y],a[i][1]); 28 for (int i=2;i<n;i++) 29 { 30 int mn=1e7,x; 31 for (int j=i;j<=n;j++) 32 if (a[j][1]<mn) mn=a[j][1],x=j; 33 if (i!=x) for (int j=1;j<=m;j++) swap(a[i][j],a[x][j]); 34 } 35 for (int i=2;i<m;i++) 36 { 37 int mn=1e7,x; 38 for (int j=i;j<=m;j++) 39 if (a[1][j]<mn) mn=a[1][j],x=j; 40 if (i!=x) for (int j=1;j<=n;j++) swap(a[j][i],a[j][x]); 41 } 42 } 43 44 void work2() 45 { 46 int x,y,mn=1e7; 47 for (int i=1;i<=n;i++) 48 for (int j=1;j<=m;j++) 49 if (b[i][j]<mn) mn=b[i][j],x=i,y=j; 50 if (x!=1) for (int i=1;i<=m;i++) swap(b[x][i],b[1][i]); 51 if (y!=1) for (int i=1;i<=n;i++) swap(b[i][y],b[i][1]); 52 for (int i=2;i<n;i++) 53 { 54 int mn=1e7,x; 55 for (int j=i;j<=n;j++) 56 if (b[j][1]<mn) mn=b[j][1],x=j; 57 if (i!=x) for (int j=1;j<=m;j++) swap(b[i][j],b[x][j]); 58 } 59 for (int i=2;i<m;i++) 60 { 61 int mn=1e7,x; 62 for (int j=i;j<=m;j++) 63 if (b[1][j]<mn) mn=b[1][j],x=j; 64 if (i!=x) for (int j=1;j<=n;j++) swap(b[j][i],b[j][x]); 65 } 66 } 67 68 int main() 69 { 70 int T=read(); 71 while (T--) 72 { 73 n=read(),m=read(); 74 for (int i=1;i<=n;i++) 75 for (int j=1;j<=m;j++) 76 a[i][j]=read(); 77 for (int i=1;i<=n;i++) 78 for (int j=1;j<=m;j++) 79 b[i][j]=read(); 80 work1();work2(); 81 int flag=0; 82 for (int i=1;i<=n;i++) 83 { 84 for (int j=1;j<=m;j++) 85 if (a[i][j]!=b[i][j]) 86 { 87 flag=1;break; 88 } 89 if (flag) break; 90 } 91 if (flag) puts("NIE"); 92 else puts("TAK"); 93 } 94 return 0; 95 }