题解:
我们把给定序列按照次序排成一列,我们可以发现,当空格左右移动时,整个序列的逆序对数不受影响,但是当空格上下移动时,我们可以发现其实就是被交换的数和他前后的n - 1
个数调换了次序,我们已知n是一个奇数,那么n - 1
必然是一个偶数,相应的逆序对的变化也会是一个偶数,所以我们判断的依据就是:两个序列的逆序对数是否奇偶性相同。
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int maxn = 3e5 + 10;
int a[maxn],b[maxn],c[maxn];
ll cnt = 0;
void merge_sort(int l,int r)
{
memset(b,0,sizeof(b));
if(l >= r) return ;
int mid = (l + r)/2;
int p = l;
int q = mid + 1;
int pos = l;
merge_sort(l,mid);
merge_sort(mid + 1,r);
while(p <= mid||q <= r){
if(q > r||(p <= mid&&a[p] <= a[q])){
b[pos++] = a[p++];
}
else {
cnt += mid - p + 1;
b[pos++] = a[q++];
}
}
for(int i = l;i <= r;i++){
a[i] = b[i];
}
}
int main()
{
int n,num = 0;
while(scanf("%d",&n)){
num = 0;
for(int i = 1;i <= n * n;i++){
int x;
cin >> x;
if(x > 0) a[++num] = x;
}
merge_sort(1,num);
ll ans1 = cnt;
cnt = num = 0;
for(int i = 1;i <= n * n;i++){
int x;
cin >> x;
if(x > 0) a[++num] = x;
}
merge_sort(1,num);
ll ans2 = cnt;
if((ans1 & 1) == (ans2 & 1)) printf("TAK\n");
else printf("NIE\n");
}
return 0;
}