[LeetCode系列]N皇后问题递归解法 -- 位操作方式
2014-08-13 16:15
316 查看
N皇后问题:
给定8*8棋盘, 放置n个皇后, 使其互相不能攻击(即2个皇后不能放在同一行/列/正反对角线上), 求解共有多少种放置方式?
这个问题的解答网上有不少, 但是位操作解法的我看到的不多. 下面贴出代码和图解, 也就不赘述了.
给定8*8棋盘, 放置n个皇后, 使其互相不能攻击(即2个皇后不能放在同一行/列/正反对角线上), 求解共有多少种放置方式?
这个问题的解答网上有不少, 但是位操作解法的我看到的不多. 下面贴出代码和图解, 也就不赘述了.
class Solution { public: /* 使用位操作实现的回溯算法. 按行扫描, 检测可以放置的列. * 'limit' - 都是 '1'. 代表着所有列都被占据了 * 'h' - 是目前所有皇后列在行上的垂直投影. 如果 h==limit, 本次搜索结束, answer++. * 'r' - 是目前所有皇后反对角线在行上的垂直投影. * 'l' - 是目前所有皇后正对角线在行上的垂直投影. * h|r|l - 是目前所有已被占据的位. 故 pos = limit & (~(h|r|l)) 就是所有的自由位置. * p = pos & (-pos) 求出最右侧的1. pos -= p 意思是在p代表的这1位上放置一个皇后. * 'h+p' - 是新增的皇后在行上的列的垂直投影. * '(r+p)<<1' 是新增的皇后反对角线的垂直投影. 因为我们移动到下一行, 投影从右至左倾斜, * 我们需要在移动到下一行后向左平移一个位置. * '(l+p)>>1' 是新增的皇后正对角线的垂直投影. 因为我们移动到下一行, 投影从左至右倾斜, * 我们需要在移动到下一行后向右平移一个位置. */ int ans, limit; int totalNQueens(int n) { ans = 0; limit = (1<<n) - 1; dfs(0, 0, 0); return ans; } void dfs(int h, int r, int l) { if (h == limit) { ans++; return; } int pos = limit & (~(h|r|l)); // 用位与去除高位0, 获取本行所有可以放置的位置 while (pos) { // 因为pos 8位以上的部分都是0, 所以下面的分析只针对低8位 int p = pos & (-pos); // 取负数的结果是pos取反+1, 再&pos结果就是取pos的最低的一位1 pos -= p; // 去除这一位 dfs(h+p, (r+p)<<1, (l+p)>>1); // 列方向限制直接加上新增的p // 对于下一行而言, 对角线限制就是p左右两侧各1个格子 } } };
相关文章推荐
- [LeetCode系列] 二叉树最大深度求解问题(C++递归解法)
- [LeetCode系列]爬梯问题的递归解法转换为迭代解法
- 算法学习记录 N皇后问题 递归解法
- K皇后问题递归解法
- [LeetCode系列]有序链表转换为平衡BST的递归解法
- [LeetCode系列] K节点倒序问题迭代解法
- n皇后问题的递归和迭代版 leetcode N-Queens
- N皇后问题递归与非递归解法
- n皇后问题的递归解法
- n皇后问题的递归解法
- 八皇后问题(递归解法)
- N皇后问题的递归与非递归解法
- [LeetCode系列]3元素最近和问题的O(n^2)解法
- C++递归问题之二——n皇后问题:以四、八皇后为例,给定n个皇后要求将它们放在一个n维矩阵中,任意两个皇后不能出现在同一行、列、主副对角线上,输出具体的摆放方式
- 八皇后问题的位操作解法
- 递归-回溯法求解8皇后问题(C)
- 八皇后问题的高效解法-递归版(转)
- n后问题迭代, 递归解法...
- 八皇后问题 C语言,递归,非递归,循环!
- 八皇后问题(递归版)