分类:algorithm| 发布时间:2016-10-15 14:14:00
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
使用回朔法可以解决这个问题。
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> ret;
string row(n, '.');
vector<string> board(n, row);
solve(board, n, 0, ret);
return ret;
}
void solve(vector<string> &board, int n, int x, vector<vector<string>> &ret) {
if (x == n) {
ret.push_back(board);
return;
}
for (int i = 0; i < n; ++i) {
if (isValid(board, n, x, i)) {
board[x][i] = 'Q';
solve(board, n, x + 1, ret);
board[x][i] = '.';
}
}
}
bool isValid(vector<string> &board, int n, int x, int y) {
for (int i = 0; i < n; ++i) {
if (i != x && board[i][y] == 'Q')
return false;
// back-diagonal
int j = y - (x - i);
if (j >= 0 && j < n && board[i][j] == 'Q')
return false;
// diagonal line
j = y + (x - i);
if (j >= 0 && j < n && board[i][j] == 'Q')
return false;
}
return true;
}
};
在判断一个位置是否合法时,需要判断这一列,45 度角线以及 135 度角线是否有另一个 Q。 可以通过 3 个辅助数组来简化判断。
/* | | | / / / \ \ \
* O O O O O O O O O
* | | | / / / / \ \ \ \
* O O O O O O O O O
* | | | / / / / \ \ \ \
* O O O O O O O O O
* | | | / / / \ \ \
* 3 columns 5 45° diagonals 5 135° diagonals (when n is 3)
*/
class Solution {
public:
std::vector<std::vector<std::string> > solveNQueens(int n) {
vector<vector<string> > res;
vector<string> board(n, string(n, '.'));
vector<int> flag_col(n, 1), flag_45(2 * n - 1, 1), flag_135(2 * n - 1, 1);
solveNQueens(res, board, flag_col, flag_45, flag_135, 0, n);
return res;
}
private:
void solveNQueens(vector<vector<string> > &res, vector<string> &board, vector<int> &flag_col, vector<int> &flag_45, vector<int> &flag_135, int row, int &n) {
if (row == n) {
res.push_back(board);
return;
}
for (int col = 0; col != n; ++col)
if (flag_col[col] && flag_45[row + col] && flag_135[n - 1 + col - row]) {
flag_col[col] = flag_45[row + col] = flag_135[n - 1 + col - row] = 0;
board[row][col] = 'Q';
solveNQueens(res, board, flag_col, flag_45, flag_135, row + 1, n);
board[row][col] = '.';
flag_col[col] = flag_45[row + col] = flag_135[n - 1 + col - row] = 1;
}
}
};