八皇后问题的规则是同一列,同一行,同一正负对角线不能冲突,即两皇后不能出现在同一列,同一行,同一正负对角线。
主要思路是对行进行遍历,再对每列进行判断,正负对角线进行判断。根据规则判断下一个皇后是否与上一个皇后冲突,当找到一种方案输出。
找到第一种排版后,将最后一行的皇后释放,继续循环遍历列,找到下一个不冲突的位置,再输出。没有找到则回溯到倒数第二行,继续找与前面皇后不冲突的位置。以此循环往复,直至回溯到第一行,然后再继续外层循环。
详细代码和注释如下:
#include <iostream>
using namespace std;
static int time=0; //计算多少种情况
int place[8]={0}; //放置皇后的位置 ,即对应行的列
bool flag[8]={1,1,1,1,1,1,1,1}; //宣布占领的位置
bool position[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; //正对角线位置
bool negative[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; //负对角线位置
void Queen(int n);
void print();
int main()
{
Queen(0);
return 0;
}
void Queen(int n)
{
int col;
for(col=0;col<8;col++) //循环遍历每一列
{
if(flag[col]&&position[n-col+7]&&negative[col+n])//判断目前列和两对角线是否冲突
{
place[n]=col; //放置皇后
flag[col]=0; //宣布占领
position[n-col+7]=0; //占领该皇后的正对角线位置
negative[n+col]=0; //占领该皇后的负对角线位置
if(n<7)
Queen(n+1); //放置下一行皇后
else //放到第七行则输出棋盘
print();
flag[col]=1; //回溯 ,复原占领的位置,考虑其他可行情况
position[n-col+7]=1;
negative[n+col]=1;
}
}
}
void print()
{
int i,j;
++time;
cout<<"第"<<time<<"个:"<<endl;
int a[8][8]={0};
for(i=0;i<8;i++)
a[i][place[i]]=1; //用8个1表示8个皇后填充到8*8棋盘的对应位置
for(i=0;i<8;i++) //输出棋盘
{
for(j=0;j<8;j++) cout<<a[i][j]<<' ';
cout<<endl;
}
}