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

    题目:Now, instead outputting board configurations, return the total number of distinct solutions.


    思路:回溯法和二进制法

    二进制法可能是目前最快的算法。

    本质上来讲,这两题没啥区别。只是再写一遍。

    首先我需要判断是否合适,行不需要判断,只需要判断列的和两个对角线的。

    判断列是在某一列,就1<<colIndex,这样,我每次只需要和原来的colflag-and一下,比如原来是11000000,现在来了一个新的00001000,这个时候and一下是0,说明有效。至于两条对角线,使用同样的方法。只不过在标志是哪条对角线,使用了一些技巧。

    接下来就是满足条件,就更新,方法是并上原来的状态。

    取消的时候就是一个数学逻辑变换。

    这里的queenHelper函数的一个变换就是,当满足8个的时候,返回1,原来是存入堆栈。在程序中一个关键的就是满足条件count要加上后来start+1的情况。



    代码:

    //切记,本题目还有一种位比较法,可以很快输出有多少个。
    
    class Solution1 {
    private:
        //https://leetcode.com/problems/n-queens-ii/
        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));
        }
        
        int queenHelper(int n, vector<string> &answer, vector<vector<string> > &result) {
            int rowIndex = answer.size();
    
            if (rowIndex == n) {
                result.push_back(answer);
                return 1;
            }
            int count=0;
            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';
                    count+=queenHelper(n, answer, result);//每一次迭代或者说是递归调用会有新的count生成,但是只是返回值,最终还是
                                                          //所有的count值。
                    answer.back()[i] = '.';
                    unsetFlag(rowIndex, i, n);
                }
            }
            answer.pop_back();
            return count;
        }
    
    public:
        int totalNQueens(int n) {
            // https://oj.leetcode.com/problems/n-queens/
    
            colFlag = diagFlag1 = diagFlag2 = 0;
            vector<vector<string> > result;
            vector<string> answer;
            
            return queenHelper(n, answer, result);
            
        }
    };


  • 相关阅读:
    HDU 6187 Destroy Walls
    HDU1596 find the safest road
    美国机遇号失联已久,NASA想出一奇招,网友看后:这我上我也行!
    萨拉飞机或掉入恐怖深渊,那里满是核废料
    Problem : 恢复一棵树
    Problem : [tju1071]一个简单题
    Problem : 马农
    人类首个“触日”探测器绕日第二圈
    美国三岁男孩森林迷路两天 遇黑熊“热心帮忙”终获救
    世上最孤独鸭子去世
  • 原文地址:https://www.cnblogs.com/jsrgfjz/p/8519901.html
Copyright © 2011-2022 走看看