N皇后与数独,回溯的较难应用

还是之前回溯的模板,只不过添加元素是要加一个判断函数。
它的递归层数可以看成是它行数,因此行数达到n时,这就是递归终止条件。
这里我用的时visited数组来表示,某一行某一列不能取。
完整代码:
点击查看代码
class Solution {
public:
vector<pair<int,int>>v;
vector<vector<pair<int,int>>>cnt;
bool judge(int x,int y,vector<bool>&visitedx,vector<bool>&visitedy){
if(visitedx[x]||visitedy[y]){return false;}
for(int i=0;i<v.size();i++){
int tempx=v[i].first;
int tempy=v[i].second;
if(x==tempx||y==tempy||abs(x-tempx)==abs(y-tempy)){return false;}
}
return true;
}
void backtracking(int n,int startflag,vector<bool>&visitedx,vector<bool>&visitedy){
if(startflag==n){
cnt.push_back(v);
return ;}
for(int j=0;j<n;j++){
if(judge(startflag,j,visitedx,visitedy)){
pair<int,int>mpair(startflag,j);
v.push_back(mpair);
visitedx[startflag]=true;
visitedy[j]=true;
backtracking(n,startflag+1,visitedx,visitedy);
v.pop_back();
visitedx[startflag]=false;
visitedy[j]=false;
}
}
}
vector<vector<string>> solveNQueens(int n) {
vector<bool>visitedx(n,false);
vector<bool>visitedy(n,false);
vector<vector<string>>fin;
backtracking(n,0,visitedx,visitedy);
for(int i=0;i<cnt.size();i++){
vector<string>cell;
for(int j=n-1;j>=0;j--){
string temp;
for(int k=0;k<n;k++){
if(cnt[i][j].second==k){temp+='Q';}
else{temp+='.';}
}
cell.push_back(temp);
}
fin.push_back(cell);
}
return fin;
}
};

数独感觉比N皇后难一些,因为涉及到了二维递归,就是有两层for循环。
因为这只要返回一个结果,因此无需用void,用bool就行,找到就return true往上返回。
N皇后和数独都是二维的图,但是数独中每一行都是要取满的,因此多出一层for循环。
而且这是直接在题目给的数组进行回溯,也就是修改。之前回溯都先将回溯的结果收集起来,之后再处理。
之前的插入元素相等于现在的在数独中写数,pop_back相当于现在重新'.';
其他的跟N皇后差不多,也是添加元素是要加一个判断函数。
点击查看代码
class Solution {
public:
bool judgeall(char val,int x,int y,vector<vector<char>>& board){
for(int i=0;i<9;i++){
if(board[x][i]==val){return false;}
}
for(int j=0;j<9;j++){
if(board[j][y]==val){return false;}
}
int startRow = (x / 3) * 3;
int startCol = (y / 3) * 3;
for (int i = startRow; i < startRow + 3; i++) { // 判断9方格里是否重复
for (int j = startCol; j < startCol + 3; j++) {
if (board[i][j] == val ) {
return false;
}
}
}
return true;
}
bool backtracking(vector<vector<char>>& board){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]=='.'){
for(char k='1';k<='9';k++){
if(judgeall(k,i,j,board)){
board[i][j]=k;
bool result=backtracking(board);
if(result){return true;}
board[i][j]='.';
}
}
return false;
}
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
};

浙公网安备 33010602011771号