zoukankan      html  css  js  c++  java
  • [LeetCode系列]N皇后问题递归解法 -- 位操作方式

    N皇后问题:

    给定8*8棋盘, 放置n个皇后, 使其互相不能攻击(即2个皇后不能放在同一行/列/正反对角线上), 求解共有多少种放置方式?

    这个问题的解答网上有不少, 但是位操作解法的我看到的不多. 下面贴出代码和图解, 也就不赘述了.

     1 class Solution {
     2     public:
     3         /* 使用位操作实现的回溯算法. 按行扫描, 检测可以放置的列.
     4          * 'limit' - 都是 '1'. 代表着所有列都被占据了
     5          * 'h' - 是目前所有皇后列在行上的垂直投影. 如果 h==limit, 本次搜索结束, answer++.
     6          * 'r' - 是目前所有皇后反对角线在行上的垂直投影.
     7          * 'l' - 是目前所有皇后正对角线在行上的垂直投影.
     8          * h|r|l - 是目前所有已被占据的位. 故 pos = limit & (~(h|r|l)) 就是所有的自由位置.
     9          * p = pos & (-pos)  求出最右侧的1. pos -= p 意思是在p代表的这1位上放置一个皇后.
    10          * 'h+p' - 是新增的皇后在行上的列的垂直投影.
    11          * '(r+p)<<1'  是新增的皇后反对角线的垂直投影. 因为我们移动到下一行, 投影从右至左倾斜,
    12          *                   我们需要在移动到下一行后向左平移一个位置. 
    13          * '(l+p)>>1'  是新增的皇后正对角线的垂直投影. 因为我们移动到下一行, 投影从左至右倾斜,
    14          *                   我们需要在移动到下一行后向右平移一个位置.
    15          */
    16         int ans, limit;
    17         int totalNQueens(int n) {
    18             ans = 0;
    19             limit = (1<<n) - 1;
    20             dfs(0, 0, 0);
    21             return ans;
    22         }
    23         void dfs(int h, int r, int l) {
    24             if (h == limit) {
    25                 ans++;
    26                 return;
    27             }
    28             int pos = limit & (~(h|r|l)); // 用位与去除高位0, 获取本行所有可以放置的位置
    29             while (pos) {
    30                 // 因为pos 8位以上的部分都是0, 所以下面的分析只针对低8位
    31                 int p = pos & (-pos); // 取负数的结果是pos取反+1, 再&pos结果就是取pos的最低的一位1 
    32                 pos -= p; // 去除这一位
    33                 dfs(h+p, (r+p)<<1, (l+p)>>1); // 列方向限制直接加上新增的p
    34                                               // 对于下一行而言, 对角线限制就是p左右两侧各1个格子
    35             }
    36         }
    37 };
  • 相关阅读:
    贪心算法 Wooden Sticks
    HDOJ 2189 悼念512汶川大地震遇难同胞——来生一起走
    hdoj1069 Monkey and Banana(最长上升子序列)
    2012级计科《程序设计基础Ⅱ》期末上机考试
    Constructing Roads In JGShining's Kingdom
    c语言学习随笔之指针(二)
    c语言学习随笔之指针(一)
    遍历网页框架结构
    笔记本测试软件(让奸商头疼的软件)0
    ResizePicturevb.net
  • 原文地址:https://www.cnblogs.com/lancelod/p/3910427.html
Copyright © 2011-2022 走看看