题目
奇数码问题
题解
这题要用模拟出结果是非常麻烦的,具体的可以看八数码问题,经过分析(我根本分析不出来)发现只要两个数组的逆序对的奇偶性相同,那就是能成功转化,那么这道题就变成了求逆序对的数目,具体如何求可参考上一题Ulter-QuickSort。但是要注意0不能算进去。
参考代码
#include<iostream>
using namespace std;
const int N = 510 * 510;
int n;
int a[N], b[N], tmp[N];
int merge_sort(int a[], int l, int r){if(l == r) return 0;int mid = l + r >> 1;int i = l, j = mid + 1, k = 0;int res = merge_sort(a, l, mid) + merge_sort(a, mid + 1, r);while(i <= mid && j <= r){if(a[i] <= a[j]) tmp[k ++] = a[i ++];else{tmp[k ++] = a[j ++];res += mid - i + 1;}}while(i <= mid) tmp[k ++] = a[i ++];while(j <= r) tmp[k ++] = a[j ++];for(int i = l, j = 0; i <= r; i ++, j ++) a[i] = tmp[j];return res % 2;
}
int main(){while(scanf("%d", &n) != EOF){int x;for(int i = 1, j = 1; i <= n * n; i ++){cin >> x;if(x) a[j ++] = x;} for(int i = 1, j = 1; i <= n * n; i ++){cin >> x;if(x) b[j ++] = x;}if(merge_sort(a, 1, n * n) == merge_sort(b, 1, n * n)) puts("TAK");else puts("NIE");}return 0;
}