/*
思路:把行当做一个一维数组处理;这样每次放置皇后是就不用考虑列的问题;放置时只要判断这个位置对应的行和对角线都没有皇后就可以放置了;
利用回溯法一个一个位置试验;直到把八列上所有皇后都放好;输出所有满足条件的行,显示其解。一下的程序解释的比较详细;呵呵,是因为我自己
也是刚学的菜鸟,搞清楚比较好。有意见欢迎提!废话不说,看程序:
*/
#include <iostream>
#ifndef __QUEEN_H__
#define __QUEEN_H__
using namespace std;
class Queen
{
private:
int n; //皇后数
bool *row; //行是否有皇后
bool *diag; //主对角线是否有皇后
bool *backDiag; //反对角线是否有皇后
int *x; //皇后问题的解
void BackTracking(int c); //用回溯法递归求解皇后问题
void Show(); //显示解
public:
Queen(int num=8); //构造函数
virtual~Queen(); //析构函数
void Run(){BackTracking(1);} //运行
};
//程序主要部分---思想
void Queen::BackTracking(int c) //前c-1个皇后已放置后,为第C个皇后选择合适的位置
{
if(c>n) Show(); //c>n;表示都放置好了,显示解即可
else
{
for(int r=1;r<=n;r++) //这里把列当成一个一元数组处理;故列不可能重复放皇后;所以放置皇后时不用判断列上是否己有皇后
{//第c个皇后放置的行
if(!row[r]&&!diag[n-c+r]&&!backDiag[c+r-1]) //要求r行同时满足该行,该主队角线,该反对角线均没放置皇后
{
row[r]=diag[n-c+r]=backDiag[r+c-1]=true; //ture了,就表示位置现(r,c)已有皇后
x[c]=r; //表示第c个(列)皇后缩放置的行(r)
BackTracking(c+1); //调用本身试探第c+1个皇后所放置的位置
row[r]=diag[n-c+r]=backDiag[r+c-1]=false; //释放位置(r,c),进行回溯
}
}
}
}
void Queen::Show() //显示解
{
static int num=0; //表示当前已求解的个数
cout<<"第"<<++num<<"个解:";
cout<<"("<<x[1]; //显示格式(x[1],x[2],...,x[n])
for(int i=2;i<=n;i++)
cout<<","<<x[i];
cout<<")"<<endl;
}
Queen::Queen(int num) //初始化皇后问题
{
n=num;
row=new bool[n+1]; //分配空间
diag=new bool[2*n];
backDiag=new bool[2*n];
x=new int[n+1];
int i; //临时变量
for(i=1;i<=n;i++) row[i]=false; //表示初始时所有行没有放置皇后
for(i=1;i<2*n;i++) diag[i]=false; //表示所有对角线没有放置皇后
for(i=1;i<2*n;i++) backDiag[i]=false;
}
Queen::~Queen() //析构函数----作用:释放空间
{
delete []row;
delete []diag;
delete []backDiag;
delete []x;
}
#endif
int main(void)
{
Queen objQueen(8); //八皇后问题对象;当然也可以求四皇后问题
objQueen.Run(); //运行求解皇后问题
system("PAUSE");
return 0;
}