奇数码问题

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; 
}

以上是关于奇数码问题的主要内容,如果未能解决你的问题,请参考以下文章

奇数码问题

奇数码问题(逆序对求解)

pbootcms对接微信扫码登录代码核心片段和步骤(前后端)

108. 奇数码问题思维 / 逆序对

AcWing:108. 奇数码问题(归并排序 + 逆序数)

C++将整数数组分割成奇数和偶数两个数组的源码