奇数码问题
Posted karshey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了奇数码问题相关的知识,希望对你有一定的参考价值。
华容道。
每次交换:左右交换或上下交换。
左右交换,数字的相对位置不会变化,逆序对数目不变;上下交换,数字的变化n-1次,逆序对则。由于n为奇数,所以数字都是偶数次变化,逆序对数目也是偶数次变化。
两个正方形数字的逆序对数目若都为奇数或都为偶数则可以达到。
ps:在做的过程中发现输入不进去,返回3221225725了,原来是堆栈爆掉了,不要在主函数里开大数组。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define pb push_back
#define fi first
#define se second
#define mem(a,x) memset(a,x,sizeof(a));
#define db double
//
const int N=510*510;
int a[N],b[N];
int temp[N];
int n;
ll ans=0;
void Merge_sort(int d[],int l,int r)
{
if(l<r)
{
int mid=(l+r)/2;
Merge_sort(d,l,mid);
Merge_sort(d,mid+1,r);
int i=l,j=mid+1,k=l;
while(i<=mid&&j<=r)
{
if(d[i]<=d[j]) temp[k++]=d[i++];
else
{
ans+=mid-i+1;
temp[k++]=d[j++];
}
}
while(i<=mid) temp[k++]=d[i++];
while(j<=r) temp[k++]=d[j++];
for(int ii=l;ii<=r;ii++) d[ii]=temp[ii];
}
else return;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n)
{
mem(a,0);mem(b,0);
if(!n) break;
n=n*n;
//cout<<n;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>b[i];
if(n==1)
{
cout<<"TAK"<<endl;continue;
}
int flag=-1;
for(int i=0;i<n;i++)
{
if(a[i]==0) flag=i;
if(flag!=-1&&i>flag) a[i-1]=a[i];
}
flag=-1;
for(int i=0;i<n;i++)
{
if(b[i]==0) flag=i;
if(flag!=-1&&i>flag) b[i-1]=b[i];
}
//
//for(int i=0;i<n;i++) cout<<a[i]<<" ";
//
ll ans1,ans2;
Merge_sort(a,0,n-2);
ans1=ans;ans=0;
Merge_sort(b,0,n-2);
ans2=ans;ans=0;
if((ans1&1)==(ans2&1)) cout<<"TAK"<<endl;
// else if(ans1%2==1&&ans2%2==1) cout<<"TAK"<<endl;
else cout<<"NIE"<<endl;
}
return 0;
}
以上是关于奇数码问题的主要内容,如果未能解决你的问题,请参考以下文章