题目链接:https://www.luogu.com.cn/problem/P3593
首先找规律,发现:只有当原矩阵中每一行每一列的元素在转换成现矩阵后,仍在同一列、同一行便可以实现。
分别记录原来每个元素的位置及现在的位置。判断位置是否符合规律即可。
注意:数据为[-1e6,1e6],所以N要大一些。
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 const int N=2*1000005; 6 int g[2*N][3]; 7 int a[1005][1005]; 8 int t,n,m,x,flag; 9 int main(){ 10 scanf("%d",&t); 11 while(t--){ 12 memset(g,0,sizeof(g)); 13 memset(a,0,sizeof(a)); 14 flag=0; 15 scanf("%d%d",&n,&m); 16 for(int i=1;i<=n;i++) 17 for(int j=1;j<=m;j++){ 18 scanf("%d",&a[i][j]); 19 g[a[i][j]+N/2][1]=i; 20 g[a[i][j]+N/2][2]=j; 21 } 22 for(int i=1;i<=n;i++) 23 for(int j=1;j<=m;j++){ 24 int x; 25 scanf("%d",&x); 26 g[x+N][1]=i; 27 g[x+N][2]=j; 28 } 29 for(int i=1;i<=n&&flag==0;i++){ 30 int t=g[a[i][1]+N][1]; 31 if(t==0) {flag=1; break;} 32 for(int j=1;j<=m;j++){ 33 if(g[a[i][j]+N][1]!=t) {flag=1; break;} 34 } 35 if(flag==1) break; 36 } 37 for(int i=1;i<=m&&flag==0;i++){ 38 int t=g[a[1][i]+N][2]; 39 if(t==0) {flag=1; break;} 40 for(int j=1;j<=n;j++){ 41 if(g[a[j][i]+N][2]!=t) {flag=1; break;} 42 } 43 if(flag==1) break; 44 } 45 if(flag) printf("NIE "); 46 else printf("TAK "); 47 } 48 return 0; 49 }