AcWing 108. 奇数码问题
考察:归并排序
n恒为奇数,所以左右上下移动不会改变逆序对的奇偶性.
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 const int N = 250010; 5 typedef long long LL; 6 int n,a[N],b[N],tmp[N]; 7 void read(int c[]) 8 { 9 for(int i=1,k =0;i<=n*n;i++) 10 { 11 int x; 12 scanf("%d",&x); 13 if(x) c[++k] = x; 14 } 15 } 16 LL merge(int l,int r,int a[]) 17 { 18 if(l>=r) return 0; 19 int mid = l+r>>1; 20 LL ans = merge(l,mid,a); 21 ans+=merge(mid+1,r,a); 22 int i = l,j = mid+1,k= 0; 23 while(i<=mid&&j<=r) 24 { 25 if(a[i]<=a[j]) tmp[k++] = a[i++]; 26 else tmp[k++] = a[j++],ans+=(long long)mid-i+1; 27 } 28 while(i<=mid) tmp[k++] = a[i++]; 29 while(j<=r) tmp[k++] = a[j++]; 30 for(int i=l;i<=r;i++) a[i] = tmp[i-l]; 31 return ans; 32 } 33 int main() 34 { 35 while(scanf("%d",&n)!=EOF) 36 { 37 read(a); 38 read(b); 39 LL k = merge(1,n*n-1,a); 40 LL t = merge(1,n*n-1,b); 41 if(((k-t)%2)==0) puts("TAK"); 42 else puts("NIE"); 43 } 44 return 0; 45 }
2021.3.5 二刷WA了N次发现read函数里的c数组写成了a
代码已经改成了二刷代码,这题的关键点在于左右不改变逆序对个数,上下移动逆序对偶数次变化.