题目如下:
题目 N皇后
设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。
首先定义棋盘二维数组chessmap,对于里面的每一个整数,0代表可放置皇后,1代表已经放置皇后,2代表已知的皇后覆盖的不可放置区域。
实现每次放置皇后后棋盘状态的修改:
void changeStatus(vector<vector<int>>& nextmap,int x,int y){
int length = nextmap.size();
for(int i=0;i<length;i++){
nextmap[x][i] = 2;
nextmap[i][y] = 2;
changeDiag(nextmap,x,y,{-1,1});
changeDiag(nextmap,x,y,{1,1});
changeDiag(nextmap,x,y,{1,-1});
changeDiag(nextmap,x,y,{-1,-1});
}
nextmap[x][y] = 1;
int offset = 0;
}
循环体里面前两行为修改行和列,修改对角线略微复杂故封装了一个新函数去修改对角线,代码如下:
void changeDiag(vector<vector<int>>& nextmap,int iptx,int ipty,vector<int> offset){
int length = nextmap.size();
int dx = offset[0];
int dy = offset[1];
int x = iptx; int y = ipty;
while(( 0<=x&&x<length ) && (0<=y&&y<length)){
nextmap[x][y] = 2;
x += dx;
y += dy;
}
}
输入的offset(偏移量)代表了修改对角线的方向(射线的方向)。
利用上述函数去搞dfs,注意迭代次数超过棋盘边长时要输出答案并且停止迭代,完整代码如下:
void dfs(vector<vector<int>> chessmap,int n,vector<vector<string>>& ans){
vector<vector<int>> nextmap = chessmap;
int length = chessmap.size();
if(n==length){
vector<string> ret(length);
for(int i=0;i<length;i++){
for(int j=0;j<length;j++){
if(chessmap[i][j]==1){
ret[i].push_back('Q');
}
else ret[i].push_back('.');
}
}
ans.push_back(ret);
return;
}
for(int i=0;i<length;i++){
if(nextmap[n][i]==0){
changeStatus(nextmap,n,i);
dfs(nextmap,n+1,ans);
nextmap = chessmap;
}
}
}
最后注意函数的顺序:修改对角线的函数需要定义在修改状态函数的前面,否则会报错(或者可以先声明函数),完整代码实现如下:
class Solution {
public:
void changeDiag(vector<vector<int>>& nextmap,int iptx,int ipty,vector<int> offset){
int length = nextmap.size();
int dx = offset[0];
int dy = offset[1];
int x = iptx; int y = ipty;
while(( 0<=x&&x<length ) && (0<=y&&y<length)){
nextmap[x][y] = 2;
x += dx;
y += dy;
}
}
void changeStatus(vector<vector<int>>& nextmap,int x,int y){
int length = nextmap.size();
for(int i=0;i<length;i++){
nextmap[x][i] = 2;
nextmap[i][y] = 2;
changeDiag(nextmap,x,y,{-1,1});
changeDiag(nextmap,x,y,{1,1});
changeDiag(nextmap,x,y,{1,-1});
changeDiag(nextmap,x,y,{-1,-1});
}
nextmap[x][y] = 1;
int offset = 0;
}
void dfs(vector<vector<int>> chessmap,int n,vector<vector<string>>& ans){
vector<vector<int>> nextmap = chessmap;
int length = chessmap.size();
if(n==length){
vector<string> ret(length);
for(int i=0;i<length;i++){
for(int j=0;j<length;j++){
if(chessmap[i][j]==1){
ret[i].push_back('Q');
}
else ret[i].push_back('.');
}
}
ans.push_back(ret);
return;
}
for(int i=0;i<length;i++){
if(nextmap[n][i]==0){
changeStatus(nextmap,n,i);
dfs(nextmap,n+1,ans);
nextmap = chessmap;
}
}
}
vector<vector<string>> solveNQueens(int n) {
int length = n;
vector<vector<string>> ans;
vector<vector<int>> chessmap(length,vector<int>(length,0));
dfs(chessmap,0,ans);
return ans;
}
};
提交,过了。