数据结构 N皇后问题
来源于国际象棋的一个问题。N后问题要求在以个nxn格的棋盘上放置n个皇后,使得它们彼此不受攻击。按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一条斜线上的其他任何棋子。因此,n后问题等价于要求在一个nxn格的棋盘上放置n个皇后,使得任何2个皇后不能被放在同一行或同一列或同一条斜线上。
求解过程从空配置开始,在第1列至第m列为合理配置的基础上,再配置第m+1列。直至第n列配置也是合理时,就找到了一个解。接着改变第n列的配置,希望获得下一个解。另外,在任何一列上可能有n种配置。开始时,配置在第1行,以后改变时顺序选择第2行,第3行,……,直到第n行。当第n行配置也找不到一个合理的配置时,就要回溯,去改变前一列的配置。得到求解皇后问题的算法如下:
#include "stdafx.h"
#include<iostream>
#include "math.h"
#include<string>
using namespace std;
class QueenChess
{
friend void setQueenChess(int n); //初始化N*N棋盘
protected:
void TrackBack();
void PlaceQueen(int row); // 在第row行放一个皇后
void DrawChess() ;//打印出N皇后的所有可能的情况
bool place(int row ,int col);//判断此位置是否安全
private:
string chessState[10000];//存放棋盘的状态
int sum,n; //记录N*N棋盘放置皇后的总数
};
//求解在N*N棋盘中 ,成功放置N皇后棋盘的总数
void QueenChess ::TrackBack()
{
PlaceQueen(1);
cout<<n<<"皇后问题总共的解的个数是:"<<sum<<endl;
}
void QueenChess::PlaceQueen(int row)
{
//在row行的所有列尝试放皇后
for(int col=1;col<=n;col++)
{
if(place(row ,col))
{
//如果(row ,col)是安全的,就放上一个皇后
chessState[row][col]='Q';
//尝试下一行
if(row<n)
PlaceQueen(row+1);
//N个皇后已经放完了,打印出棋盘,sum加一
else
{
sum++;
DrawChess();
}
}
//此位置不安全,
chessState[row]="------------------------------------";
}
}
bool QueenChess::place(int row, int col)
{
int qRow ,qCol;
for(qRow=1;qRow<row ;qRow++)
{
string Q=chessState[qRow];
qCol=Q.find("Q");
if((abs(qCol-col))==(abs(qRow-row))||qCol==col)
return false ;
}
return true ;
}
void QueenChess ::DrawChess()
{
int i,j;
cout<<n<<"皇后问题的第"<<sum<<"个解为:"<<endl;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
cout<<chessState[i][j]<<" ";
cout<<endl;
}
}
//对棋盘进行初始化
void setQueenChess(int n)
{
QueenChess X;
X.n=n;
X.sum=0;
for(int i=1;i<=n;i++)
X.chessState[i]="------------------------------------";
X.TrackBack();
}
void main()
{
cout<<"请输入在N*N棋盘中放入的皇后个位:"<<endl;
int n;
cin>>n;
setQueenChess(n);
}