006回溯法——n皇后问题

     在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

     代码如下:

//nQueen
//by xcz on 2013.9.10

#include <iostream>
#include "math.h"

using namespace std;

//记录解空间的节点信息
class Queen
{
	friend int nQueen(int);
private:
	bool Place(int k);
	void Backtrack(int t);
	int n,	//皇后的个数
		*x;	
	//n元组x[1:n]表示n后问题的解,其中,x[i]表示皇后i放在棋盘的第i行的第x[i]列,两两要互不相等;
	long sum;	//可行解数量

};



//检测解的可行性,剪枝函数
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]))	//判断斜线有没有皇后,其斜线斜率为+1,-1,或者看其下标之差或者之和是否相等
			return false;                               //后面是判断是否在同一列
		
	}
	return true;
}

//采用递归回溯遍历解空间树,解空间树为子集树
void Queen::Backtrack(int t)
{
	if (t>n)
	{
		sum++;		//t为解空间层数,当搜索到n以后,说明解可行
		for (int i=1 ;i<=n ; ++i)
		{
			cout<<x[i]<<" ";
		}
		cout<<endl;
	}
	else
		for (int i=1 ; i<=n ;++i)
		{
			x[t] =i;
			if(Place(t))
				Backtrack(t+1);
		}
}

int nQueen(int n)
{
	Queen X;
	//初始化X
	X.n = n;
	X.sum = 0;
	int *p = new int[n+1];
	for (int i=0 ; i<=n ; ++i)
		p[i]=0;
	X.x=p;
	X.Backtrack(1);
	delete []p;
	return X.sum;
}

int main()
{
	int n=8,ans;
	cout<<n<<"皇后问题的解为:"<<endl;
	ans = nQueen(n);
	cout<<n<<"皇后问题共有"<<ans<<"个不同的解"<<endl;
	system("pause");
	return 0;
}

另:今天是教师节,祝那些可敬的老师们节日快乐,另外还要感谢csdn无私的博主们,以及百度 and google~~


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值