一般是八皇后,首先是算法思想如下:
void generate(int n){
int col;
for(col=0;col<=7;col++){
if(不冲突){
放置,并且宣布占领
if(n<7){
generate(n+1);
}else{
printf();//打印
}
回溯,取消占领.
}
}
}
主函数如下:首先从0开始,也就是第一行开始逐级向下
int main(){
generate(0);
cout<<"摆放方式有:"<<counts<<"种!"<<endl;
return 0;
}
递归函数如下:
void generate(int n){
int col;
for(col=0;col<8;col++){//棋盘一共八行八列,此处主要是每一层用于判断每一列是否符合条件
if(flag[col]&&d1[n-col+7]&&d2[n+col]){//括号内是算法的精髓,理解了此处,N皇后问题就不难,主要是根据八皇后棋盘的性质,
//如两个坐标,如果行数-列数对应的值相同,那么就必然在同一对角线,此时跳出if从而判断下一位置
Queens[n]=col;//符合上述条件之后,就把皇后放置在col列,并且把相对于的列,上对角线,下对角线的标记改为false,方便之后的判断
flag[col]=false;
d1[n-col+7]=false;
d2[n+col]=false;
if(n<7){
generate(n+1);
}else{
print();
}
flag[col]=true;//回溯考虑上一层的情况,并且把这一层改过来的false改为true
d1[n-col+7]=true;
d2[n+col]=true;
}
}
}
输出函数如下:
void print(){
int col,i,j;
counts++;
cout<<"No."<<counts<<endl;
int table[8][8]={};//定义一个8*8的棋盘数组,起始每个元素都是0
for(col=0;col<8;col++){
table[col][Queens[col]]=1;//Queens[col]保存的是皇后所在的列数
}
for(i=0;i<8;i++){
for(j=0;j<8;j++){
cout<<table[i][j]<<" ";
}
cout<<endl;
}
}
头部声明以及全局变量如下:
#include <iostream>
#include <algorithm>
using namespace std;
int Queens[8]={};//表示第n个皇后占位置的列号
int counts=0;//counts记录能摆放的棋盘方式个数
bool flag[8]={1,1,1,1,1,1,1,1};//标志数组,表示第col列是否可占,1表示可占
bool d1[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//表示上对角线是否可占 为什么是15呢?
//因为在d1[n-col+7]中为了避免出现负数,所以要+7,而原来可能是7的现在变成了14
bool d2[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//表示下对角线是否可占