zoukankan      html  css  js  c++  java
  • N-Queens

    题目:The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.


    Given an integer n, return all distinct solutions to the n-queens puzzle.

    Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

    For example,
    There exist two distinct solutions to the 4-queens puzzle:

    [
     [".Q..",  // Solution 1
      "...Q",
      "Q...",
      "..Q."],
    
     ["..Q.",  // Solution 2
      "Q...",
      "...Q",
      ".Q.."]
    ]


    思路:回溯或者二进制法

    思路很清晰,首先我是每行插入一个,所以行的问题不需要考虑,然后就是需要判断列和两个对角线的问题。判断的程序是一个难题:主要就是八个位判断

    1<<colIndex  代表第几列的时候,向左移位colIndex位,如果有效(此时为0),此时就要setFlag,并操作,因为,我刚刚就是已经有代表哪几个位已经占据的标志了。至于后面的unsetFlag函数,只是通过某种数学逻辑关系进行运算,返回原来的状态。colFlag&~(1<<colIndex)。

    在真正的主程序里面,首先定义rowIndex为answer的数组,一旦满了,就保存进堆栈。因为最大只能到n-1的。

    首先在answer放入n个’.',然后从0到n-1 开始遍历,先是判断是否满足,不满足直接return,满足,开始更新各个flag值,此时answer已经存入一组数,满足了,可以存入堆栈,然后开始下一层,这个时候,还是从0开始一个个判断,发现,总有不能满足的。继续下一个i值。

    值得注意的是,每个循环里面,在加入q之后,为了下一列的判断,还得出栈,退出q,不然程序出错。

    answer的进栈和出栈也是对称的。总之,回溯法是对称的。


    代码:

    class Solution {
    private:
        int colFlag;//代表列
        int diagFlag1;//index=i+j
        int diagFlag2;//index=n-1+i-j
        
        bool isValid(int rowIndex,int colIndex,int n){
            //行不需要判断,因为我是按照行走的
            //为0说明有效
            if( (1<<colIndex)&colFlag ){
                //为1 无效
                return false;
            }
            if( (1<<(rowIndex+colIndex))&diagFlag1  ){
                return false;
            }
            if( (1<<(n-1+rowIndex-colIndex) ) & diagFlag2 ){
                return false;
            }
            return true;
        }
        
        void setFlag(int rowIndex,int colIndex,int n){
            colFlag   |=(1<<colIndex);
            diagFlag1 |=(1<<(rowIndex+colIndex));
            diagFlag2 |=(1<<(n-1+rowIndex-colIndex));
        }
        
        
        void unsetFlag(int rowIndex, int colIndex, int n) {
            colFlag &= ~(1 << colIndex);
            diagFlag1 &= ~(1 << (rowIndex + colIndex));
            diagFlag2 &= ~(1 << (n + rowIndex - colIndex - 1));
        }
        
        void queenHelper(int n, vector<string> &answer, vector<vector<string> > &result) {
            int rowIndex = answer.size();
    
            if (rowIndex == n) {
                result.push_back(answer);
                return;
            }
            
            answer.push_back(string(n, '.'));
            for (int i = 0; i < n; i++) {
                if (isValid(rowIndex, i, n)) {
                    setFlag(rowIndex, i, n);
                    answer.back()[i] = 'Q';
                    queenHelper(n, answer, result);
                    answer.back()[i] = '.';
                    unsetFlag(rowIndex, i, n);
                }
            }
            answer.pop_back();
        }
    
    public:
        vector<vector<string> > solveNQueens(int n) {
            // https://oj.leetcode.com/problems/n-queens/
    
            colFlag = diagFlag1 = diagFlag2 = 0;
            vector<vector<string> > result;
            vector<string> answer;
    
            queenHelper(n, answer, result);
            return result;
        }
    };


  • 相关阅读:
    R语言代写混合时间模型预测对时间序列进行点估计
    python代写安娜卡列妮娜词云图制作
    R语言代写markov switching model马尔可夫转换分析研究水资源
    R语言代写markov switching model马尔可夫转换模型研究商业周期
    Python代写数据可视化-seabornIris鸢尾花数据
    R语言代写聚类算法的应用实例
    用TensorFlow代写实现MNIST
    R语言代写Copula的贝叶斯非参数估计
    r语言代写预测波动率的实现:ARCH模型与HAR-RV模型
    CF932E Team Work 第二类斯特林数
  • 原文地址:https://www.cnblogs.com/jsrgfjz/p/8519903.html
Copyright © 2011-2022 走看看