用C++实现8皇后问题+代码
首先感谢B站小姐姐耐心讲解
主要思路:
- 用二维列表表示摆放皇后后的攻击位置,(即1表示不可放,0表示可放),记为attack。如图


- 每行放置一个皇后后,更新attack,然后遍历下一行的每列,通过判断该位置是否为0,寻找可放位置(注意要备份attack,以回溯)
- 关于棋盘用一维queen来表示,用“.”表示空,“Q”表示皇后

- 最后将每种棋盘摆放方法记录
代码:
#include<iostream>
#include<vector>
using namespace std;
vector<vector<string>> solveNQueens(int n);
void backtrack(int k, int n, vector<string>& queen, vector<vector<int>>& attack, vector<vector<string>>& solve);//k表示下一个需要摆放皇后行位置
void put_queen(int x, int y, vector<vector<int>>& attack);
int main() {
vector<vector<string>> res; //保存棋盘摆放情况
res = solveNQueens(8);
cout << "8皇后问题一共有"<<res.size()<<"种情况"<<endl;
//展示
cout << "结果如下:" << endl;
for (int i = 0; i < res.size(); i++) {
cout << "第" << i+1 << "种" << endl;
for (int j = 0; j < res[i].size(); j++) {
cout << res[i][j] << endl;
}
}
return 0;
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> solve; //保存最终结果
vector<vector<int>> attack; //保存皇后攻击位置 0表示不攻击;1表示攻击
vector<string>queen; //保存皇后位置
//1.初始化
for (int i = 0; i < n; i++) {
attack.push_back(vector<int>());
for (int j = 0; j < n; j++) {
attack[i].push_back(0);
}
queen.push_back("");
queen[i].append(n, '.');//结尾添加n个.
}
//求
backtrack(0, n, queen, attack, solve);
return solve;
}
void backtrack(int k, int n, vector<string>& queen, vector<vector<int>>& attack, vector<vector<string>>& solve)
{
if (k == n) {
//找到一组解
solve.push_back(queen);
return;
}
//
for (int i = 0; i < n; i++) { //遍历第k行的每一列,找到可以放皇后的位置
if (attack[k][i] == 0) { //找到
vector<vector<int>> temp = attack;//备份,便于回溯
queen[k][i] = 'Q'; //皇后位置标记为Q
put_queen(k, i, attack);//放皇后后,更新attack
backtrack(k + 1, n, queen, attack, solve);//递归,试探第k+1行能不能放皇后
attack = temp;//回溯,回复attack,查找其他可能
queen[k][i] = '.';//取消皇后放置位置
}
}
}
void put_queen(int x, int y, vector<vector<int>>& attack)
{
//放置皇后后,更新attack
static const int dx[] = { -1,-1,-1,0,1,1,1,0 };
static const int dy[] = { -1,0,1,1,1,0,-1,-1 };
attack[x][y] = -1;
for (int i = 1; i < attack.size(); i++) {
for (int j=0;j<8;j++)
{
int nx = x + i * dx[j];
int ny = y + i * dy[j];
if (nx >= 0 && nx < attack.size() && ny >= 0 && ny < attack.size()) {
attack[nx][ny] = -1;
}
}
}
}
运行结果部分截图:
