1. 程式人生 > >奇數碼問題(逆序對求解)

奇數碼問題(逆序對求解)

ger amp sort Go nil scan printf 序列 註意

兩個矩陣,排成線性序列,若逆序對奇偶性相同,則可以互相轉化矩陣

註意: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; }

奇數碼問題(逆序對求解)