奇数码问题(逆序对求解)
两个矩阵,排成线性序列,若逆序对奇偶性相同,则可以互相转化矩阵
注意:0不算入内,
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const ll nil=20000000000; const int maxn=500000+10; ll L[maxn/2],R[maxn/2]; int n; ll a[maxn]; int top; ll megersort(int l,int r,int mid,ll a[]){ int n1=mid-l; int n2=r-mid; ll cnt=0; int i,j; for (i=0;i<n1;i++) L[i]=a[l+i]; for (j=0;j<n2;j++) R[j]=a[mid+j]; L[n1]=nil; R[n2]=nil; i=j=0; for (int k=l;k<r;k++){ if(L[i]<=R[j]){ a[k]=L[i++]; } else { a[k]=R[j++]; cnt=((cnt%2)+(mid+j-k-1)%2)%2; } } return cnt%2; } ll meger(int l,int r,ll a[]){ if(l+1<r){ int mid=(l+r)>>1; ll v1=meger(l,mid,a); ll v2=meger(mid,r,a); ll v3=megersort(l,r,mid,a); return (v1%2+v2%2+v3%2)%2; } else return 0; } int main(){ while(scanf("%d",&n)!=EOF){ memset(R,0,sizeof(R)); top=-1; int x; for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ scanf("%d",&x); if(x!=0) a[++top]=x; } } ll ans1=meger(0,top+1,a); memset(a,0,sizeof(a)); memset(L,0,sizeof(L)); memset(R,0,sizeof(R)); top=-1; for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ scanf("%d",&x); if(x!=0) a[++top]=x; } } ll ans2=meger(0,top+1,a); if(ans1%2==ans2%2) printf("TAK\n"); else printf("NIE\n"); //printf("%lld %lld\n",ans1,ans2); } return 0; }