按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1
输出:[[“Q”]]
提示:
- 1 <= n <= 9
回溯法
#include<iostream>
#include<string>
#include<vector>
using namespace std;
bool judgeValid(vector<string> board, int curRow, int curCol, int queenNum) {
vector<vector<string>> res;
//由于每次均row+1,不存在同行存在的可能
//判断是否同列
for (int r = 0; r < queenNum; r++){
if (board[r][curCol] == 'Q') {
return false;
}
}
//判断是否同在左斜线(由于是按行从上到下,依次放置,因此只用判断左上角,不用判断右下角)
for (int i = curRow - 1, j = curCol - 1; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 'Q') {
return false;
}
}
//判断是否同在右斜线(由于是按行从上到下,依次放置,因此只用判断右上角,不用判断左下角)
for (int i = curRow - 1, j = curCol + 1; i >= 0 && j < queenNum; i--, j++) {
if (board[i][j] == 'Q') {
return false;
}
}
return true;
}
void backtrack(vector<string> &board, vector<vector<string>> &res, int row, int queenNum) {
if (row == queenNum){
res.push_back(board);
return;
}
for (int col = 0; col < queenNum; col++){
if (judgeValid(board,row,col,queenNum)){
board[row][col] = 'Q';
backtrack(board, res, row + 1, queenNum);//穷尽在当前情况下,下一行怎样放置
board[row][col] = '.';//回溯(寻找第一行放置不同列情况下有多少种可能)
}
}
}
vector<vector<string>> solveNQueens(int queenNum) {
//生成棋盘
vector<vector<string>> res;//存储最终结果
vector<string> board(queenNum, string(queenNum, '.'));//生成棋盘
backtrack(board, res, 0, queenNum);//回溯法求解所有结果
return res;
}
int main() {
int queenNum = 5;
vector<vector<std::string>> res = solveNQueens(queenNum);
for (const auto& row : res) {
for (const auto& col : row) {
std::cout << col << " ";
}
std::cout << std::endl; // 换行
}
system("pause");
return 0;
}