在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~~