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);
    }
};
posted @ 2024-01-19 13:59  yun-che  阅读(14)  评论(0)    收藏  举报