N皇后很明显是一个NP—Hard问题,如果n足够大的话,在有限较短的时间内是很难得出答案的,但是注意到N皇后(笔者认为这类问题称为棋盘问题更为贴切),在n*n棋盘之上,每个点有且只有两种状态,这与电脑自身的进制非常类似,因此很自然的想到状态压缩,通过二进制码来表示原先通过数组来表示的皇后状态,也就是我们从原先的二维问题转换为一维问题

这边补充一些前置知识:

神奇的位运算:

kk & (kk-1) : 可以将kk的二进制码的最右边的1去掉

eg: 10010 & (10010-1) = 10010 & 10001 = 10000

kk & -kk : 可以将kk最左边的1提取出来

eg: 10010 & -10010 = 10010 & 01110 = 00010

这边熟悉补码的读者应该非常熟悉在计算机中,负数的补码的第二种算法是从右往左直到第一个1为止都与原码相通后面的则与原码相反

即100 10的补码是011 10,所以这个位运算可以通过这个定义方式来帮助理解

~kk : 可以将kk的值反转

eg: ~10010 = 01101

那么这样子我们就可以通过vis,L,R这三个二进制码来分别表示,列,副对角线,主对角线的情况,笔者会在下面逐渐讲出

熟悉N皇后的读者应该直到,N皇后其实可以从原先的n*n的子序列,降级为1-n的列排序,因此行在这边仅作为终止标志

vis是记录列的皇后情况我们使用1表示有皇后,即1001表示第一列和第四列有皇后

L和R的实现方法类似,因此不失一般性的,笔者就之讲解L的代表含义

L表示的是副对角线的情况,这边可以这样考虑如果是1,那么该列就在前面皇后的副对角线上

这边我们考虑当前层是cur层,我们已经确定insert=00010是合法的皇后位置,此时L=01010

那么此时我们要如此操作:

L = insert | L; 这边表示的含义是将当前层合法的皇后位置加入L中

L = L << 1; 想一想,在cur+1层,L的影响是不是上一层L的影响总体都往左移动一位

注意下面0表示空,1表示皇后,2表示皇后的副对角线影响位置

cur :02010 (此时L=01010)

cur+1:20200 (此时L=10100)

最后就是对前面神奇的位运算的收尾了:

很明显vis|L|R中含有1的位置都是非法的皇后位置,即此时合法填充的皇后位置该处应为0

我们不妨用valid来表示当前皇后可以放置的位置

那么很自然的想到valid = ~(vis|L|R)

其实就是不可以的补集就是可行集

当然仅仅是这样仍然是不行的,因为我们使用的整数类型未必都是n位,因此前面会多出许多1,所以我们还需要base = (1<<n) - 1;来维护n位的问题

所以valid = base & !(vis|L|R)

那么接下来通过老朋友dfs的组装就可以见到全新版本的位运算n皇后,只能说位运算真的很神奇

点击查看笔者代码
void dfs(int cur, int vis, int L, int R) {
if(cur == n) { cnt++; return; }
int temp = base&~(vis | L | R);
while(temp) {
int insert = temp & -temp;
temp = temp ^ insert;//这行等价于temp = temp & (temp-1),想想为什么
dfs(cur+1, vis|insert, (L | insert) << 1, (R | insert) >> 1);
}
}

N皇后的位运算有感的更多相关文章

  1. N皇后问题(位运算实现)

    本文参考Matrix67的位运算相关的博文. 顺道列出Matrix67的位运算及其使用技巧 (一) (二) (三) (四),很不错的文章,非常值得一看. 主要就其中的N皇后问题,给出C++位运算实现版 ...

  2. [CODEVS1295]N皇后(位运算+搜索)

    题目描述 Description 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个皇后,任 ...

  3. 洛谷 1219:八皇后 (位运算 & DFS)

    题目链接: https://www.luogu.org/problem/show?pid=1219#sub row:受上面的皇后通过列控制的位置 ld:受上面的皇后通过从右至左的斜对角线控制的位置 r ...

  4. 【位运算经典应用】 N皇后问题

    说到位运算的经典应用,不得不说N皇后问题. 学过程序设计的都知道N皇后问题,没听过也没关系.很简单,最传统的的N皇后问题是这个样子的,给你一个n * n大小的board,让你放n个皇后(国际象棋),要 ...

  5. N皇后-位运算优化

    N皇后问题 时间限制: 5 Sec  内存限制: 128 MB 题目描述 魔法世界历史上曾经出现过一个伟大的罗马共和时期,出于权力平衡的目的,当时的政治理论家波利比奥斯指出:“事涉每个人的权利,绝不应 ...

  6. N皇后解法以及位运算优化

    N皇后解法以及位运算优化 观察棋盘,要求皇后之间不能处在同行同列同一条斜线,求使得每行都有一个皇后的放置方法共有多少种. 每尝试放置一个皇后,都可以把该位置所在的行.列标号用一个数组标记,含义表示该行 ...

  7. N皇后问题 --使用位运算解决

    关键位运算 x & (-x) 取得最低位1 x & (x-1) 去掉最低位1 class Solution(object): def totalNQueens(self, n): &q ...

  8. JavaScript 位运算总结&拾遗

    最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个 ...

  9. BZOJ 1087 互不侵犯King (位运算)

    题解:首先,这道题可以用位运算来表示每一行的状态,同八皇后的搜索方法,然后对于限制条件不相互攻击,则只需将新加入的一行左右移动与上一行相&,若是0则互不攻击,方案可行.对于每种方案,则用递推来 ...

随机推荐

  1. EdgeFormer: 向视觉 Transformer 学习,构建一个比 MobileViT 更好更快的卷积网络

    ​  前言 本文主要探究了轻量模型的设计.通过使用 Vision Transformer 的优势来改进卷积网络,从而获得更好的性能. 欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结.最新技术跟 ...

  2. NS2中couldn‘t read file “../tcl/mobility/scene/cbr-3-test“: no such file or directory解决方法

    运行wireless.tcl 文件时报错:couldn't read file "../../uAMPS/ns-leach.tcl": no such file or direct ...

  3. 【面试普通人VS高手系列】说一说Mybatis里面的缓存机制

    一个工作了 5年的程序员,在私信里面不断向我诉苦. 他说,他用了Mybatis这么久,怎么滴也算是精通Mybatis了吧. 结果竟然在Mybatis这个面试题上翻车了! 真的好烦! 好吧,我们今天来看 ...

  4. python 动态规划(背包问题和最长公共子串)

    背包问题 现在要往一个可以装4个单位重量的背包里怎么装价值最高:A重量1个单位,价值15:B重量3个单位,价值20:C重量4个重量,价值30 使用动态规划填充空格 class SolutionBag: ...

  5. SpringBoot 2.X 快速掌握

    0.重写博文的原因 当初我的SpringBoot系列的知识是采用分节来写的,即:每一个知识点为一篇博文,但是:最近我霉到家了,我发现有些博文神奇般地打不开了,害我去找当初的markdown笔记,但是方 ...

  6. UniqueMergeTree:支持实时更新删除的 ClickHouse 表引擎

    UniqueMergeTree 开发的业务背景 首先,我们看一下哪些场景需要用到实时更新. 我们总结了三类场景: 第一类是业务需要对它的交易类数据进行实时分析,需要把数据流同步到 ClickHouse ...

  7. numpy中shape的部分解释

    转载自:https://blog.csdn.net/qq_28618765/article/details/78081959和https://www.jianshu.com/p/e083512e4f4 ...

  8. 2020 CSP-J 初赛游记

    估分 预估 85 分,一是怕选错,而是最后真的错了一些 考点 排列组合:论临时抱佛脚的作用 靠前看了一下捆绑法和插板法,果然考了. 2.算法常识,和复杂度分析 冒泡排序最小交换次数 = n-1 , G ...

  9. CYaRon!语

    P3695 CYaRon!语 开始之前 上次水了些小模拟之后感觉不能再颓废了,于是就来大模拟. 然后这个题花了我一个多星期 还是最差解 不过,为了纪念我的第 20 道紫题,纪念我这一周的努力,我还是想 ...

  10. Django从数据库导model迁移乱码

    python manage.py inspectdb > [your app name]\models.py 执行后 model.py乱码,将models.py以 UTF-16LE打开.