leetcode N-Queens/N-Queens II, backtracking, hdu 2553 count N-Queens, dfs

原创 2015年07月09日 02:07:25
  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\n",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.

LeetCode 52. N-Queens II(N皇后)

原题网址:https://leetcode.com/problems/n-queens-ii/ Follow up for N-Queens problem. Now, instead...
  • jmspan
  • jmspan
  • 2016年05月21日 06:27
  • 290

leetCode 52.N-Queens II (n皇后问题II) 解题思路和方法

N-Queens II Follow up for N-Queens problem. Now, instead outputting board configurations, ...
  • xygy8860
  • xygy8860
  • 2015年07月13日 14:08
  • 1128

LeetCode 51. N-Queens和52. N-Queens II的位运算解法

LeetCode 51. N-Queens和52. N-Queens II的位运算解法
  • u011433274
  • u011433274
  • 2016年09月09日 17:00
  • 434

[LeetCode][Java] N-Queens II

题目: Follow up for N-Queens problem. Now, instead outputting board configurations, return the...
  • Evan123mg
  • Evan123mg
  • 2015年07月15日 10:51
  • 753

N-Queens -- LeetCode

原题链接: http://oj.leetcode.com/problems/n-queens/  N皇后问题是非常经典的问题了,记得当时搞竞赛第一道递归的题目就是N皇后。因为这个问题是典型的NP问题...
  • linhuanmars
  • linhuanmars
  • 2014年03月07日 00:32
  • 25913

N-Queens II -- LeetCode

原题链接: http://oj.leetcode.com/problems/n-queens-ii/  这道题跟N-Queens算法是完全一样的,只是把输出从原来的结果集变为返回结果数量而已。思路我...
  • linhuanmars
  • linhuanmars
  • 2014年03月07日 00:34
  • 9969

【Leetcode】:51. N-Queens 问题 in JAVA

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...
  • u013564276
  • u013564276
  • 2016年04月25日 19:16
  • 769

【LeetCode with Python】 N-Queens

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...
  • nerv3x3
  • nerv3x3
  • 2014年09月21日 17:44
  • 9892

LeetCode --- 51. N-Queens

题目链接:N-Queens The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that...
  • makuiyu
  • makuiyu
  • 2015年03月07日 10:46
  • 1497

N-Queens N皇后问题@LeetCode

经典的8皇后,递归回溯可解。同时还学了StringBuffer里面一个setCharAt()很方便的方法 package Level4; import java.util.ArrayList;...
  • hellobinfeng
  • hellobinfeng
  • 2013年11月11日 04:55
  • 2631
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:leetcode N-Queens/N-Queens II, backtracking, hdu 2553 count N-Queens, dfs
举报原因:
原因补充:

(最多只允许输入30个字)