八皇后问题
八皇后问题
8 x 8的棋盘上保证每一行、每一列和两个斜列上只有一个皇后。
递归分析
程序结构:
- 初始化
- 循环八次:
- 放置一个皇后
- 若满足防止条件则放置皇后
- 若不满足则回退,增加一步再放置
- 直到放置到最后一个皇后
自相似的关系提取
- 过程:
- 找到N个皇后的适合位置
- 划分:
- 找到第N-1个皇后合适的位置
- 找到第N个皇后的位置
- 递归终止条件
- 找到最后一个皇后的位置
算法流程
- Step1:
- 数据初始化
- Step2:
- 从col列开始摆放第n个皇后,挨个测试列是否可行,需要先测试当前位置是否安全:
- 若安全,摆放第n个皇后,并且宣布占领(横竖撇捺都要占领)
- 若未测试完所有的的行
- 递归测试下一行
- n = N-1 时打印结果
- 如果当n >= N-1时说明无法摆放或摆放完毕时需要回溯
- 从col列开始摆放第n个皇后,挨个测试列是否可行,需要先测试当前位置是否安全:
- Step3:
- 输出结果
数据结构
- place:int数组【0....7】
- 第n行皇后所占位置的列号
- 主要用于输出结果
- flag:bool数组【0....7】
- 表示col列上能放置皇后
- d1:bool数组【0....14】
- (n,col)所在上对角线上是否可以放置皇后 (n-col+7)(保证为正)
- d2:bool数组【0....14】
- (n,col)所在下对角线上是否可以放置皇后(n+col)
程序思路
-
是否能放置
- flag[col] and d1[n-col+1] and d2[n+col]
-
放置皇后
- place[n] := col;
- flag[col] := false;
- d1[n-col+7] := false;
- d2[n+col] := false;
-
删除皇后(回溯:探求所有可能):
- flag[col] := true;
- d1[n-col+1] := true;
- d2[n+col] := true;
代码
/*
八皇后问题
*/
#include <stdio.h>
#include <iostream>
using namespace std;
//初始化
int place[8] = {0};
bool flag[8] = {1,1,1,1,1,1,1,1};
bool d1[15] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
bool d2[15] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int number = 0;
void print(){
int col,i,j;
number++;
cout<<"No."<<number<<endl;
int table[8][8] = {0};
for(col = 0;col < 8;col++){
table[col][place[col]] = 1;
}
for(i = 0;i < 8;i++){
for(j = 0;j < 8;j++){
cout<<table[i][j]<<" ";
}
cout<<endl;
}
}
void generate(int n){
int col;
for(col = 0;col < 8;col++){
if(flag[col] && d1[n-col+7] && d2[n+col]){
place[n] = col;
flag[col] = 0;
d1[n-col+7] = 0;
d2[n+col] = 0;
if(n < 7){
generate(n+1);
}
else{
print();
}
//回溯
flag[col] = 1;
d1[n-col+7] = 1;
d2[n+col] = 1;
}
}
}
int main(int argc, char const *argv[])
{
generate(0);
return 0;
}
浙公网安备 33010602011771号