奇数码问题

Posted hhyx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了奇数码问题相关的知识,希望对你有一定的参考价值。

# 题意
奇数码为八数码的扩展,即为n的正方形矩阵,n为奇数,给定一个初始局面,一个最终局面,判断能否从初始局面到达最终局面。

# 题解
1) 两个局面可达当且仅当两个局面中除了空格中的数意外展成一行后(不考虑空格)即n*n - 1个数字,逆序对个数的奇偶性相同
2) 必要性:

空格左右移动的时候,序列不变,空格上下移动的时候,相当于某个数与它前或后边的n-1个数交换了位置,因为n-1是偶数,所以逆序对的变化个数也只能是偶数。
当n为偶数的时候,结论:两个局面可达当且仅当两个局面对应网格展成序列后,(逆序对数之差)和(两个局面下空格所在的行数之差)奇偶性相同。

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=510;
 5 int a[N*N];
 6 int b[N*N];
 7 int ans[N*N];
 8 int merge_sort(int a[],int l,int r){
 9    if(r-l<1)
10       return 0;
11 
12    int mid=(l+r)>>1;
13 
14    int res=0;
15    res+=merge_sort(a,l,mid);
16    res+=merge_sort(a,mid+1,r);
17 
18    int k = 0,i = l,j = mid+1;
19    while(i <= mid && j <= r){
20       if(a[i] <= a[j])
21          ans[k++]=a[i++];
22       else{
23          ans[k++]=a[j++];
24          res+=mid-i+1;
25       }
26    }
27 
28    while(i <= mid)
29       ans[k++] = a[i++];
30    while(j <= r)
31       ans[k++] = a[j++];
32 
33    for(int i = l,j = 0; i <= r; i++,j++)
34       a[i]=ans[j];
35    return res;
36 }
37 int main(){
38    ios::sync_with_stdio(0);
39    cin.tie(0);
40    cout.tie(0);
41 
42    int n;
43    while(cin>>n) {
44       int ok=0,x;
45       for(int i = 1;i <= n*n;i++)
46       {
47          cin>>x;
48          if(x==0)
49             ok=1;
50          else
51             a[i-ok] = x;
52       }
53       ok=0;
54       for(int i = 1;i <= n*n;i++)
55       {
56          cin>>x;
57          if(x==0)
58             ok=1;
59          else
60             b[i-ok] = x;
61       }
62       memset(ans,0,sizeof ans);
63       int num1 = merge_sort(a, 1, n*n-1);
64       memset(ans,0,sizeof ans);
65       int num2 = merge_sort(b, 1, n*n-1);
66 
67       if((num1&1 ) == (num2&1) )
68          printf("TAK
");
69       else
70          printf("NIE
");
71    }
72 }

 

 

 

以上是关于奇数码问题的主要内容,如果未能解决你的问题,请参考以下文章

奇数码问题

奇数码问题(逆序对求解)

pbootcms对接微信扫码登录代码核心片段和步骤(前后端)

108. 奇数码问题思维 / 逆序对

AcWing:108. 奇数码问题(归并排序 + 逆序数)

C++将整数数组分割成奇数和偶数两个数组的源码