这是上篇博客 广度优先遍历(一) 全排列
前言
八皇后问题和解数独问题是回溯算法的经典例题。
依然建议大家自己动手先试试,体会体会。
回溯算法框架:
八皇后问题
1)在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
2)思考
① 8x8的棋盘要放8个皇后,所以每一行能且只能放一个皇后。
②放完第 i 行之后,下一行的皇后放在哪里呢?
答:放在下一行的、和前 i 行放置的皇后不冲突的位置。
③什么时候返回一个结果?
答:成功放置第8行的皇后之后。
class Solution {
public:
int count = 0; //统计一共有多少种方法
int eight_queen() {
vector<int*> p;//保存已经放置的棋子
bfs(0, p);
return count;
}
void bfs(int start,vector<int*> p) {
if (start == 8) { //成功完成放置
cout << setw(2) << count+1 << ") ";
for (int* i : p) {
cout <<"["<< i[0] << "," << i[1] <<"] ";
}
cout << endl;
count++;
return;
}
for (int j = 0; j < 8; j++) { //未完成放置
if (isFree(start,j,p)) {
int a[2] = { start,j };
p.push_back(a); //决策
bfs(start + 1, p); //向下遍历
p.pop_back(); //撤销决策
}
else continue;
}
}
//检查这个位置是否与其他皇后冲突
bool isFree(int x,int y,const vector<int*> &path) {
bool res = true;
for (int* i : path){
res = res && (x != i[0] && y != i[1] && (abs(x - i[0]) != abs(y - i[1])));
if (res == false) break;
}
return res;
}
};