@geek-sjl
2018-10-31T10:28:48.000000Z
字数 1191
阅读 396
总体的思路是深度优先搜索,枚举棋子摆放的位置。问题的难点就是如何剪枝,让解答树尽可能的少。
1. 以行为单位,而不是以(x,y)为单位进行枚举。emmm..肯定的啦,每行只能放一个。
2. 通过一个数组来记录某一列是否被放有棋子,如果放有则不再放置。
3. 建立一个数学关系,让在同一斜行(对角线?)的点的横纵坐标经过该数学关系运算后为一个定值。这个关系有两种。
class Solution {
public:
bool isOccupiedy[20];
bool isDiagonalA[20];
bool isDiagonalB[20];
int ansX[16];
vector<vector<string>> ans;
void dfs(int nowy,int n){
if(nowy==n+1){
vector<string> tmpAns;
for(int i=1;i<=n;i++){
string tmpStrAns="";
for(int j=1;j<=n;j++){
if(ansX[i]==j) tmpStrAns+="Q";
else tmpStrAns+=".";
}
tmpAns.push_back(tmpStrAns);
}
ans.push_back(tmpAns);
return;
}
for(int nowx=1;nowx<=n;nowx++){
int DiagonalA=nowx-nowy+n;
int DiagonalB=nowx-(n+1-nowy)+n;
// !isOccupiedy[DiagonalA]&&!isOccupiedy[DiagonalB]
if(!isOccupiedy[nowx]&&!isDiagonalA[DiagonalA]&&!isDiagonalB[DiagonalB]){
ansX[nowy]=nowx;
isOccupiedy[nowx]=true;
isDiagonalA[DiagonalA]=true;
isDiagonalB[DiagonalB]=true;
dfs(nowy+1,n);
isOccupiedy[nowx]=false;
isDiagonalA[DiagonalA]=false;
isDiagonalB[DiagonalB]=false;
}
}
}
vector<vector<string>> solveNQueens(int n) {
dfs(1,n);
return ans;
}
};