八皇后问题
最后更新于:2022-04-01 10:11:46
题意描述:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
可从行出发考虑,对于第一行中的第一个位置都考虑其摆放一个皇后,然后移动到下一行第一个位置,并考虑在该位置摆放皇后是否会造成攻击,若是则考虑该行的下一个位置;如不是则继续考虑下一行,直到八个皇后都被放置。
总的来说就是采用深度搜索加上迭代的方法来解决这个问题。
~~~
//八皇后问题,采用回溯法
#include<iostream>
using namespace std;
int g_nQueenLoc[8][8];
int nLeftToRight[15] = {0}; //对角线是否有皇后
int nRightToLeft[15] = {0};
int nRow[8] = {0};
int g_nQueenDown = 0; //已经放置的皇后数目
int g_nTotalNum = 0; //可能的解数目
void printQueen()
{
cout<<endl<<"第"<<g_nTotalNum<<"种放置方法为:"<<endl;
for(int i = 0; i< 8; i++)
{
for (int j = 0; j < 8; j++)
{
cout<<" ";
if (g_nQueenLoc[i][j])
{
cout<<"█";
}
else
cout<<g_nQueenLoc[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
void PutQueenDown(int xParm, int yParm)
{
int left2Right = 7 - xParm + yParm;
int Right2Left = xParm + yParm;
if(nLeftToRight[left2Right] == 0 && nRightToLeft[Right2Left] == 0 && nRow[yParm] == 0) //表明该位置可以放置皇后
{
nLeftToRight[left2Right] = 1; //标记该位置已经放置皇后
nRightToLeft[Right2Left] = 1;
nRow[yParm] = 1;
g_nQueenLoc[xParm][yParm] = 1;
g_nQueenDown++;
if (g_nQueenDown != 8)
{
PutQueenDown(xParm+1, 0);
}
else if (g_nQueenDown == 8)
{
g_nTotalNum++;
printQueen();
}
//还原该位置
g_nQueenDown--;
nLeftToRight[left2Right] = 0;
nRightToLeft[Right2Left] = 0;
nRow[yParm] = 0;
g_nQueenLoc[xParm][yParm] = 0;
}
if (yParm == 7)
{
return;
}
else
PutQueenDown(xParm, yParm+1);
}
int main()
{
cout<<"八皇后问题"<<endl;
memset(g_nQueenLoc, 0, sizeof(g_nQueenLoc));
PutQueenDown(0, 0);
cout<<"共有解法"<<g_nTotalNum<<"种"<<endl;
system("pause");
return 0;
}
~~~
运行结果:其中方块表示皇后所在的位置
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-02-18_56c5c49b3f5fd.jpg)