八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
解题思路:
我们按行判断,从上到下,如果某个位置有效,则置“Q”,无效则置“.”。主要的问题就是判断该位置是否有效,是否是危险位置(会产生冲突)。我们要判断本行、本列、此斜线上都没有皇后存在,此时才可以在这个位置上放置皇后。代码如下:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int queenNum=8;
int count=0;
vector<vector<string> > solveNQueens(int n);
void Nqueen(int row,int n,vector<vector<string>> &chess);
bool notDanger(int row,int j,vector<vector<string>> chess);
void main()
{
vector<vector<string>> chess;
vector<string> temp(queenNum,".");
for (int i=0;i<queenNum;i++)
{
chess.push_back(temp);
}
chess= solveNQueens(queenNum);
}
vector<vector<string> > solveNQueens(int n) {
vector<vector<string>> chess;
vector<string> temp(queenNum,".");
for (int i=0;i<queenNum;i++)
{
chess.push_back(temp);
}
Nqueen(0,queenNum,chess);
cout<<"共有:"<<count<<"种分布"<<endl;
return chess;
}
void Nqueen(int row,int n,vector<vector<string>> &chess)
{
vector<vector<string>> chess2;
chess2=chess;
if (queenNum==row)
{
cout<<"第"<<count+1<<"种分布"<<endl;
for (int i=0;i<queenNum;i++)
{
for (int j=0;j<queenNum;j++)
{
cout<<chess2[i][j];
}
cout<<endl;
}
cout<<endl<<endl;
count++;
}
else
{
for (int j=0;j<n;j++)
{
if (notDanger(row,j,chess))//判断是否危险
{
for (int i=0;i<queenNum;i++)
{
chess2[row][i]=".";
}
chess2[row][j]="Q";
Nqueen(row+1,n,chess2);
}
}
}
}
bool notDanger(int row,int j,vector<vector<string>> chess)
{
bool flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;
//判断列方向
for (int i=0;i<queenNum;i++)
{
if (chess[i][j]!=".")
{
flag1=1;
break;
}
}
//判断左上方
for (int i=row,k=j;i>=0&&k>=0;i--,k--)
{
if (chess[i][k]!=".")
{
flag2=1;
break;
}
}
//判断左下方
for (int i=row,k=j;i<queenNum&&k>=0;i++,k--)
{
if (chess[i][k]!=".")
{
flag3=1;
break;
}
}
//判断右上方
for (int i=row,k=j;i>=0&&k<queenNum;i--,k++)
{
if (chess[i][k]!=".")//
{
flag4=1;
break;
}
}
//判断右下方
for (int i=row,k=j;i<queenNum&&k<queenNum;i++,k++)
{
if (chess[i][k]!=".")
{
flag5=1;
break;
}
}
if (flag1||flag2||flag3||flag4||flag5)
{
return false;
}
else
return true;
}
代码中我们可以更改queueNum的值来计算n皇后的问题。