N-Queens(n皇后)
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'
and '.'
both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
分析:
n皇后问题很经典,以前上算法课的时候,老师曾仔细讲过。照着以前书上的讲解实现了一下
这里的约束条件是:任何两个皇后都不能位于同一条对角线上,也不能在同一直线上。这里安排第k个皇后放在第k行,我们要做的是找到它放在第k行的哪一列。
这里定义一个全局的变量vector<int> X,X[k]代表第k个皇后放在第k行的第X[k]列。不能在同一对角线上的表达式abs(i-k)!=abs(X[i]-X[k]),不能在同一
直线上的表达是X[i]!=X[k].这里约束条件可以用一个bool函数Place表述。进入此过程时,已经设置好了k-1个皇后的位置,此时检验第k个皇后的位置X[k]
是否与前k-1个位置有冲突。
有了place函数后,用回溯解决n皇后问题。如下所示,其中print函数将一个可行解表达出来。
class Solution {
vector
X;
//如果第k个皇后能放在第X[k]列,则返回true.X是一个全程数组,进入此过程时,已经设置了k-1个值,检验第k个皇后的位置X[k]
//是否与前k-1个皇后的位置有冲突
bool Place(int k)
{
int i=0;
while(i
print(vector
X)
{
int n=X.size();
vector
r(n);
string s;
for(int i=0;i
> solveNQueens(int n) { X.resize(n); vector
> sr; int k; X[0]=-1;k=0;//k是当前行,从第0列开始,所以初始时设为-1,因为有X[k]=X[k]+1; while(k>=0) { X[k]=X[k]+1;//转到下一列 while(X[k]
s; s=print(X); sr.push_back(s); }else { k++;//转到下一行 X[k]=-1; } } else//所有列都不行,回溯 k--; } return sr; } };
//update: 2017.5.29
递归的方法
class Solution {
vector<vector<string>> ans;
public:
vector<vector<string>> solveNQueens(int n) {
vector<string> ss(n,string(n,'.'));
dfs(0,n,ss);
return ans;
}
void dfs(int row,int n,vector<string> &ss)
{
if(row>=n)
{
ans.push_back(ss);
return;
}else{
for(int col=0;col<n;col++)
{
if(ok(ss,row,col,n))
{
ss[row][col]='Q';
dfs(row+1,n,ss);
ss[row][col]='.';//重置
}
}
}
}
bool ok(vector<string> & ss,int row,int col,int n)
{
int i,j;
//1.检查竖
for(int i=0;i<row;i++)
if(ss[i][col]=='Q')
return false;
//2.检查正对角线
i=row-1;j=col-1;
while(i>=0&&j>=0)
{
if(ss[i--][j--]=='Q')
return false;
}
//3.检查斜对角线
i=row-1;j=col+1;
while(i>=0&&j<n)
{
if(ss[i--][j++]=='Q')
return false;
}
return true;
}
};