Odd number problem
描述
你一定玩过八数码游戏,它实际上是在一个3*3的网格中进行的,1个空格和1~8这8个数字恰好不重不漏地分布在这3*3的网格中。
例如:
5 2 8
1 3 _
4 6 7
在游戏过程中,可以把空格与其上、下、左、右四个方向之一的数字交换(如果存在)。
例如在上例中,空格可与左、上、下面的数字交换,分别变成:
5 2 8 5 2 _ 5 2 8
1 _ 3 1 3 8 1 3 7
4 6 7 4 6 7 4 6 _
奇数码游戏是它的一个扩展,在一个n*n的网格中进行,其中n为奇数,1个空格和1~n*n-1这n*n-1个数恰好不重不漏地分布在n*n的网格中。
空格移动的规则与八数码游戏相同,实际上,八数码就是一个n=3的奇数码游戏。
现在给定两个奇数码游戏的局面,请判断是否存在一种移动空格的方式,使得其中一个局面可以变化到另一个局面。
输入格式
多组数据,对于每组数据:
第1行一个整数n,n<500,n为奇数。
接下来n行每行n个整数,表示第一个局面。
接下来n行每行n个整数,表示第二个局面。
局面中每个整数都是0~n*n-1之一,其中用0代表空格,其余数值与奇数码游戏中的意义相同,保证这些整数的分布不重不漏。
输出格式
对于每组数据,若两个局面可达,输出TAK,否则输出NIE。
样例输入
3 1 2 3 0 4 6 7 5 8 1 2 3 4 5 6 7 8 0 1 0 0
样例输出
TAK TAK
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 //#include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 //#include<queue> 8 //#include<set> 9 #define INF 0x3f3f3f3f 10 #define N 250005 11 #define re register 12 #define Ii inline int 13 #define Il inline long long 14 #define Iv inline void 15 #define Ib inline bool 16 #define Id inline double 17 #define ll long long 18 #define Fill(a,b) memset(a,b,sizeof(a)) 19 #define R(a,b,c) for(register int a=b;a<=c;++a) 20 #define nR(a,b,c) for(register int a=b;a>=c;--a) 21 #define Min(a,b) ((a)<(b)?(a):(b)) 22 #define Max(a,b) ((a)>(b)?(a):(b)) 23 #define Cmin(a,b) ((a)=(a)<(b)?(a):(b)) 24 #define Cmax(a,b) ((a)=(a)>(b)?(a):(b)) 25 #define D_e(x) printf("\n&__ %d __&\n",x) 26 #define D_e_Line printf("-----------------\n") 27 #define D_e_Matrix for(re int i=1;i<=n;++i){for(re int j=1;j<=m;++j)printf("%d ",g[i][j]);putchar('\n');} 28 using namespace std; 29 // The Code Below Is Bingoyes's Function Forest. 30 Ii read(){ 31 int s=0,f=1;char c; 32 for(c=getchar();c>'9'||c<'0';c=getchar())if(c=='-')f=-1; 33 while(c>='0'&&c<='9')s=s*10+(c^'0'),c=getchar(); 34 return s*f; 35 } 36 Iv print(ll x){ 37 if(x<0)putchar('-'),x=-x; 38 if(x>9)print(x/10); 39 putchar(x%10^'0'); 40 } 41 /* 42 Iv Floyd(){ 43 R(k,1,n) 44 R(i,1,n) 45 if(i!=k&&dis[i][k]!=INF) 46 R(j,1,n) 47 if(j!=k&&j!=i&&dis[k][j]!=INF) 48 Cmin(dis[i][j],dis[i][k]+dis[k][j]); 49 } 50 Iv Dijkstra(int st){ 51 priority_queue<int>q; 52 R(i,1,n)dis[i]=INF; 53 dis[st]=0,q.push((nod){st,0}); 54 while(!q.empty()){ 55 int u=q.top().x,w=q.top().w;q.pop(); 56 if(w!=dis[u])continue; 57 for(re int i=head[u];i;i=e[i].nxt){ 58 int v=e[i].pre; 59 if(dis[v]>dis[u]+e[i].w) 60 dis[v]=dis[u]+e[i].w,q.push((nod){v,dis[v]}); 61 } 62 } 63 } 64 Iv Count_Sort(int arr[]){ 65 int k=0; 66 R(i,1,n) 67 ++tot[arr[i]],Cmax(mx,a[i]); 68 R(j,0,mx) 69 while(tot[j]) 70 arr[++k]=j,--tot[j]; 71 } 72 Iv Merge_Sort(int arr[],int left,int right,int &sum){ 73 if(left>=right)return; 74 int mid=left+right>>1; 75 Merge_Sort(arr,left,mid,sum),Merge_Sort(arr,mid+1,right,sum); 76 int i=left,j=mid+1,k=left; 77 while(i<=mid&&j<=right) 78 arr[i]<=arr[j]? 79 tmp[k++]=arr[i++]: 80 tmp[k++]=arr[j++],sum+=mid-i+1;//Sum Is Used To Count The Reverse Alignment 81 while(i<=mid)tmp[k++]=arr[i++]; 82 while(j<=right)tmp[k++]=arr[j++]; 83 R(i,left,right)arr[i]=tmp[i]; 84 } 85 Iv Bucket_Sort(int a[],int left,int right){ 86 int mx=0; 87 R(i,left,right) 88 Cmax(mx,a[i]),++tot[a[i]]; 89 ++mx; 90 while(mx--) 91 while(tot[mx]--) 92 a[right--]=mx; 93 } 94 */ 95 int n,m,a[N],tmp[N]; 96 Iv Merge_Sort(int arr[],int left,int right,int &sum){ 97 if(left>=right)return; 98 int mid=left+right>>1; 99 Merge_Sort(arr,left,mid,sum),Merge_Sort(arr,mid+1,right,sum); 100 int i=left,j=mid+1,k=left; 101 while(i<=mid&&j<=right) 102 (arr[i]<=arr[j])? 103 tmp[k++]=arr[i++]: 104 (tmp[k++]=arr[j++],sum+=mid-i+1);//Sum Is Used To Count The Reverse Alignment 105 while(i<=mid)tmp[k++]=arr[i++]; 106 while(j<=right)tmp[k++]=arr[j++]; 107 R(i,left,right)arr[i]=tmp[i]; 108 } 109 #define PutTAK printf("TAK\n") 110 #define PutNIE printf("NIE\n") 111 int main(){ 112 int n; 113 while(scanf("%d",&n)!=EOF){ 114 int sum_start=0,sum_end=0; 115 n*=n; 116 if(!n) 117 PutNIE; 118 //Judge Case Of n=0 Specially 119 if(n==1){ 120 (read()==read())? 121 PutTAK: 122 PutNIE; 123 continue; 124 } //Judge Case Of n=1 Specially 125 int cnt_num=0; 126 R(i,1,n){ 127 int num=read(); 128 if(num) 129 a[++cnt_num]=num; 130 } 131 Merge_Sort(a,1,cnt_num,sum_start); 132 cnt_num=0; 133 R(i,1,n){ 134 int num=read(); 135 if(num) 136 a[++cnt_num]=num; 137 } 138 Merge_Sort(a,1,cnt_num,sum_end); 139 ((sum_start&1)==(sum_end&1))? 140 PutTAK: 141 PutNIE; 142 } 143 return 0; 144 } 145 /* 146 Note: 147 Error: 148 */