1. 题目
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
- LeetCode 52题,类似要求的是方案数,不用枚举出来。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
可参考:回溯算法(Backtracking Algorithm)之八皇后问题
class Solution {
vector<vector<string>> ans;
public:
vector<vector<string>> solveNQueens(int n) {
vector<string> map(n,string(n,'.'));
for(int i = 0; i < n; ++i)
{
map[0][i]='Q';
dfs(map,0,i,n);
map[0][i]='.';
}
return ans;
}
bool isok(vector<string>& map, int x, int y, int &n)
{
int i = 1, j = y;
while(x >= 1)//向上遍历,看冲突不
{
if(map[x-1][j]=='Q')//竖直方向
return false;
if(j-i>=0 && map[x-1][j-i]=='Q')//左45度
return false;
if(j+i<n && map[x-1][j+i]=='Q')//右45度
return false;
i++;//45度张角
x--;//往上找
}
return true;
}
void dfs(vector<string>& map, int x, int y, int& n)
{
if(x==n-1)
ans.push_back(map);
for(int i = 0; i < n; ++i)
{ //x+1下一行
if(x+1 < n && isok(map,x+1,i,n))
{
map[x+1][i] = 'Q';
dfs(map, x+1, i, n);
map[x+1][i] = '.';
}
}
}
};
class Solution {
int sum = 0;
public:
int totalNQueens(int n) {
vector<string> map(n,string(n,'.'));
for(int i = 0; i < n; ++i)
{
map[0][i]='Q';
dfs(map,0,i,n);
map[0][i]='.';
}
return sum;
}
bool isok(vector<string>& map, int x, int y, int &n)
{
int i = 1, j = y;
while(x >= 1)//向上遍历,看冲突不
{
if(map[x-1][j]=='Q')//竖直方向
return false;
if(j-i>=0 && map[x-1][j-i]=='Q')//左45度
return false;
if(j+i<n && map[x-1][j+i]=='Q')//右45度
return false;
i++;//45度张角
x--;//往上找
}
return true;
}
void dfs(vector<string>& map, int x, int y, int& n)
{
if(x==n-1)
sum++;
for(int i = 0; i < n; ++i)
{ //x+1下一行
if(x+1 < n && isok(map,x+1,i,n))
{
map[x+1][i] = 'Q';
dfs(map, x+1, i, n);
map[x+1][i] = '.';
}
}
}
};