XMU 1098 N皇后

#include<iostream>
#include<cmath>
#include<time.h>
using namespace std;
const unsigned long maxshort=65536L;
const unsigned long multiplier=1194211693L;
const unsigned long adder=12345L;
class RandomNumber
{
private:
	unsigned long randSeed;
public:
	RandomNumber(unsigned long s=0);
	unsigned short Random(unsigned long n);
	double fRandom(void);
};

RandomNumber::RandomNumber(unsigned long s)
{
	if(s==0)
		randSeed=time(0);
	else 
		randSeed=s;
}
unsigned short RandomNumber::Random(unsigned long n)
{
	randSeed = multiplier * randSeed + adder;
	return (unsigned short) ((randSeed>>16) % n);
}
double RandomNumber::fRandom(void)
{
	return Random(maxshort)/double(maxshort);
}
class Queen
{
	friend bool nQueen(int);
private:
	bool place(int k);
	bool backtrack(int t);
	bool queenLV(int stopLV);
	int n ,*x,*y;
};

bool Queen::place(int k)
{
	for(int j=1;j<k;j++)
		if((abs(k-j)==abs(x[j]-x[k])) || (x[j]==x[k]))
			return false;
	return true;
}

bool Queen::backtrack(int t)
{
	if(t>n)
	{
		for(int i=1;i<=n;i++)
			y[i]=x[i];
		return true;
	}
	else
		for(int i=1;i<=n;i++)
		{
			x[t]=i;
			if(place(t) && backtrack(t+1))
				return true;
		}
		return false;
}

bool Queen::queenLV(int stopLV)
{
	RandomNumber rnd;
	int k=1;
	int count=1;
	while((k<= stopLV ) && (count>0))
	{
		count=0;
		for(int i=1;i<=n;i++)
		{
			x[k]=i;
			if(place(k))
				y[count++]=i;
		}
		if(count>0)
			x[k++]=y[rnd.Random(count)];
	}
	return (count>0);

}

bool nQueen(int n)
{
	Queen X;
	X.n=n;
	int *p=new int[n+1];
	int *q=new int[n+1];
	for(int i=0;i<=n;i++)
	{
		p[i]=0;
		q[i]=0;
	}
	X.y=p;
	X.x=q;
	int stop=5;
	if(n<5)
		stop=1;
	if(n>15)
		stop=n-15;
	bool found = false;
	while(!X.queenLV(stop));
	if(X.backtrack(stop+1))
	{
		for(int i=1;i<=n;i++)
			cout<<i<<" "<<p[i]<<endl;
		found = true;
	}
	delete[] p;
	delete[] q;
	return found;
}

int main()
{
	int n;
	cin>>n;
	while(!nQueen(n));
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值