Leetcode一般的な質問に答えると、分析要約し、集約--T51(N女王)

件名の説明:

Nクイーン問題の研究はどのようにチェス盤の場所Nクイーンにはn * nは、クイーンズお互いにお互いを攻撃しません。

整数nを考えると、さまざまなソリューションクイーン問題Nのすべてを返します。

トピック分析:

解決するために、バックトラックの典型的なこの問題。エッセンスは、すべての可能な解決策を見つけるために目的を達成するように、すべての領域を横断する、暴力的な検索です。

それぞれの行、列は、対角現れるだけ女王を許し、その過程で、バックトラックアルゴリズムを使用して全ての溶液は、対象満たす意味見つけることができ、互いに女王が発生攻撃を防止するために。

class Solution{
    public:
    void DFS(int k, int n, vector<vector<int>>& matrix, vector<vector<string>>&res, vector<string>& location){
        if(k==n)  //k表示现在回溯的行数,如果已经全部遍历完成,则表示找到一组解
        {
            res.push_back(location);
            return;
        }
       //i为当前第k行的列数
        for(int i=0;i<n;i++)
        {
            if(matrix[k][i]==0) //0表示当前位置可以放皇后
            {
                //存储当前数组,方便回溯
                vector<vector<int>> before =matrix;
                //把当前位置置为Q
                location[k][i]='Q';
                //模拟棋盘数组放入皇后
                put_down_the_queen(k,i,matrix);
                //进行下一行的判断
                DFS(k+1,n,matrix,res,location);
                //回溯过程,若第k+1行的所有位置都不行,则找第k行i之后的下一个可行位置
                matrix = before;
                location[k][i]='.';
            }
        }
    }

    void put_down_the_queen(int x,int y,vector<vector<int>>& matrix){
        //用dx,dy的变化来表示皇后可以攻击的8个方位(左、右、上、下,左上,左下,右上,右下)
        static const int dx[]={-1,1,0,0,-1,-1,1,1};
        static const int dy[]={0,0,-1,1,-1,1,-1,1};
        //让皇后所在的位置置为1
        matrix[x][y]=1;
        
        for(int i=1;i<matrix.size()-1;i++)
        {
            //j代表方向,皇后的攻击方向总共有8个
            for(int j=0;j<8;j++)
            {
                //找到延展方向的下标
                int new_x=x+i*dx[j];
                int new_y=y+i*dy[j];
                //若下标在棋盘的范围之内,则将所在的位置置为1
                if(new_x>=0&&new_x<matrix.size()&&new_y>=0&&new_y<matrix.size())
                {
                    matrix[new_x][new_y]=1;
                }
            }
        }
    }


    vector<vector<string>> solveNQueens(int n){
        vector<vector<string>> res;  //用来返回结果
        if(n<0)   return res;
        vector<string>  location; //表示中间结果
        vector<vector<int>> matrix;  //表示模拟棋盘数组
        //对matrix和location进行初始化
        for(int i=0;i<n;i++)
        {
            string s="";
            vector<int> tmp;
            for(int j=0;j<n;j++)
            {
                s.push_back('.');
                tmp.push_back(0);  //赋值为0
            }
            location.push_back(s);
            matrix.push_back(tmp);  //棋盘中的每一个元素都设置为0
        }

        //进行递归回溯
        DFS(0,n,matrix,res,location);
        return res;


    }
};

対処方法2は:その後、バックトラック条件の違反がある場合は、試合への攻撃を置いているだけの女王kの銀行の前で、世界的なアナログボードを変更する必要はありません。

class Solution {
public:
    vector<vector<string>> res;
    //检查该位置是否可以放置Q,判断的时候不需要全局,只需要查看前x行即可
    bool check(vector<string>& temp,int x,int y,int n){
        int _x=x, _y=y;
        //向上查找
        while(_x>=0){
            if(temp[_x][_y]=='Q')return false;
            --_x;
        }
        _x=x;
        //左上查找
        while(_x>=0 && _y>=0){
            if(temp[_x][_y]=='Q')return false;
            --_x,--_y;
        }
        _x=x,_y=y;
        //右上查找
        while(_x>=0 && _y<n){
            if(temp[_x][_y]=='Q')return false;
            --_x,++_y;
        }
        return true;
    }
    //dfs,只有行数增加即可
    void helper(vector<string>& temp, int n, int x){
        if(x==n){
            res.push_back(temp);
            return ;
        }
        //判断该行的每列是否可以放置Q
        for(int j=0;j<n;j++){
            if(check(temp,x,j,n)){
                temp[x][j]='Q';
                helper(temp,n,x+1);
                temp[x][j]='.';
            }
        }
    }
    vector<vector<string>> solveNQueens(int n) {
        string t;
        for(int i=0;i<n;i++){
            t+='.';
        }
        vector<string>temp(n,t);
        helper(temp,n,0);
        return res;
        
    }
};

 

公開された56元の記事 ウォン称賛7 ビュー4469

おすすめ

転載: blog.csdn.net/weixin_44504987/article/details/104387961