zoukankan      html  css  js  c++  java
  • leetcode N-Queens/N-Queens II, backtracking, hdu 2553 count N-Queens, dfs 分类: leetcode hdoj 2015-07-09 02:07 102人阅读 评论(0) 收藏

    1. for the backtracking part, thanks to the video of stanford cs106b lecture 10 by Julie Zelenski for the nice explanation of recursion and backtracking, highly recommended.

    2. in hdu 2553 cout N-Queens solutions problem, dfs is used.
      // please ignore, below analysis is inaccurate, though for inspiration considerations, I decided to let it remain.
      and we use a extra occupied[] array to opimize the validation test, early termination when occupied[i]==1, and in function isSafe the test change from 3 to 2 comparisons.
      for the improvement, here is an analysis:
      noted that total call of dfs for n is less than factorial(n), for convenience we take as factorial(n),
      in this appoach, in pow(n,n)-factorial(n) cases, we conduct one comparison, and three for others
      otherwise, for all pow(n,n) cases, we must conduct three comparisons,
      blow is a list for n from 1 to 10,

       n        n!           n^n   n!/n^n
       1        1             1   1.00000
       2        2             4   0.50000
       3        6            27   0.22222
       4       24           256   0.09375
       5      120          3125   0.03840
       6      720         46656   0.01543
       7     5040        823543   0.00612
       8    40320      16777216   0.00240
       9   362880     387420489   0.00094
      10  3628800   10000000000   0.00036

    the table shows that, for almost all of the cases of large n (n>=4), we reduce 3 to 1 comparison in doing validation check.

    occupied[i] is initilized to 0, before dfs, mark.

    occupied[val]=1;

    after dfs, unmark,

    occupied[val]=0;

    where val is the value chosen.
    inspirations from chapter 3 Decompositions of graphs
    in Algorithms(算法概论), Sanjoy Dasgupta University of California, San Diego Christos Papadimitriou University of California at Berkeley Umesh Vazirani University of California at Berkeley.

    // leetcode N-Queens(12ms)

    class Solution {
        vector<vector<string>> ans;
        int N;
        //int numofsol;
    
        void AddTo_ans(string &conf) {
            vector<string> vecstrtmp;
            string strtmp(N,'.');
            for(auto ind: conf) {
                vecstrtmp.push_back(strtmp);
                vecstrtmp.back()[(size_t)ind-1]='Q';
            }
            ans.push_back(vector<string>());
            ans.back().swap(vecstrtmp);
        }
        void RecListNQueens(string soFar, string rest) {
            if(rest.empty()) {
                //++numofsol;
                AddTo_ans(soFar);
            }
            else {
                int i,j,len=soFar.size(), flag;
                for(i=0;i<rest.size();++i) {
                    for(j=0;j<len;++j) {
                        flag=1;
                        if(soFar[j]-rest[i]==len-j || soFar[j]-rest[i]==j-len) {
                            flag=0; break;
                        }
                    }
                    if(flag) RecListNQueens(soFar+rest[i],rest.substr(0,i)+rest.substr(i+1));
                }
            }
        }
    public:
        vector<vector<string>> solveNQueens(int n) {
            ans.clear();
            //numofsol=0;
            N=n;
            string str;
            for(int i=1;i<=n;++i) str.push_back(i);
            RecListNQueens("", str);
            return ans;
        }
    };

    // with a tiny modification,
    // leetcode N-Queens II (8ms)

    class Solution {
        //vector<vector<string>> ans;
        int N;
        int numofsol;
    
        /*void AddTo_ans(string &conf) {
            vector<string> vecstrtmp;
            string strtmp(N,'.');
            for(auto ind: conf) {
                vecstrtmp.push_back(strtmp);
                vecstrtmp.back()[(size_t)ind-1]='Q';
            }
            ans.push_back(vector<string>());
            ans.back().swap(vecstrtmp);
        }*/
        void RecListNQueens(string soFar, string rest) {
            if(rest.empty()) {
                ++numofsol;
                //AddTo_ans(soFar);
            }
            else {
                int i,j,len=soFar.size(), flag;
                for(i=0;i<rest.size();++i) {
                    for(j=0;j<len;++j) {
                        flag=1;
                        if(soFar[j]-rest[i]==len-j || soFar[j]-rest[i]==j-len) {
                            flag=0; break;
                        }
                    }
                    if(flag) RecListNQueens(soFar+rest[i],rest.substr(0,i)+rest.substr(i+1));
                }
            }
        }
    public:
        int totalNQueens(int n) {
            //ans.clear();
            numofsol=0;
            N=n;
            string str;
            for(int i=1;i<=n;++i) str.push_back(i);
            RecListNQueens("", str);
            return numofsol;
        }
    };

    // hdu 2553, 15ms

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    
    class countNQueenSol {
        static const int MAXN=12;
        static int values[MAXN];
        static int occupied[MAXN];
        static std::vector<int> ans;
        static int cnt, rownum;
    
        static bool isSafe(int val, int row) {
            for(int i=0;i<row;++i) {
                if(val-values[i]==row-i || val-values[i]==i-row)
                return false;
            }
            return true;
        }
        static void dfs(int row) {
            if(row==rownum) ++cnt;
            for(int i=0;i<rownum;++i) {
                if(occupied[i]==0 && isSafe(i,row)) {
                    values[row]=i;
                    occupied[i]=1;
                    dfs(row+1);
                    occupied[i]=0;
                }
            }
        }
    public:
        static int getMAXN() { return MAXN; }
        static int solve(int k) {
            if(k<=0 || k>=countNQueenSol::MAXN) return -1;
            if(ans[k]<0) {
                cnt=0;
                rownum=k;
                dfs(0);
                //if(k==0) cnt=0; // adjust anomaly when k==0
                ans[k]=cnt;
            }
            return ans[k];
        }
    };
    int countNQueenSol::values[countNQueenSol::MAXN]={0};
    int countNQueenSol::occupied[countNQueenSol::MAXN]={0};
    std::vector<int> countNQueenSol::ans(countNQueenSol::MAXN,-1);
    int countNQueenSol::cnt, countNQueenSol::rownum;
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
        int n;
        while(scanf("%d",&n)==1 && n>0) {
            printf("%d
    ",countNQueenSol::solve(n));
        }
        return 0;
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。// p.s. If in any way improment can be achieved, better performance or whatever, it will be well-appreciated to let me know, thanks in advance.

  • 相关阅读:
    asp.net 进行发送邮箱验证
    获取微信签名,并保存在xml文件中
    webform获取微信用户的授权
    [转载]将json字符串转换成json对象
    使用authentication进行身份验证,与Forms表单登陆
    解决在IE下LABEL中IMG图片无法选中RADIO的几个方法
    php网页切图/js切图
    最近新装系统windows8.1+Mac。。。还没装驱动就遇到一堆问题。。。
    百度地图api根据定位获取附近商家(只获取屏幕内)
    ios ZBar扫二维码奇奇怪怪的错误
  • 原文地址:https://www.cnblogs.com/qeatzy/p/4716220.html
Copyright © 2011-2022 走看看