本文参考Matrix67的位运算相关的博文。

顺道列出Matrix67的位运算及其使用技巧 (一) (二) (三) (四),很不错的文章,非常值得一看。

主要就其中的N皇后问题,给出C++位运算实现版本以及注释分析。

皇后问题很经典,就不再赘述问题本身,解决皇后问题,一般采用的都是深搜DFS+回溯的方法,按照行(列)的顺序枚举每一个可以放置的情况,然后进行冲突判断,当前的放置是否合法,合法就继续搜索下一层,不合法就搜索就回溯。直到,找到一个合法的解,每一层都有一个皇后并且不发生冲突,这时候,放置的方案数计1.

位运算也是采用的也是深搜加回溯的方法,但是优点在于使用位运算进行冲突的检测,这使代码简洁高效,而且还加快了运行速度。

下面的两张图来自Matrix67的(三):

                                            

depth 表示当前要进行搜索的层,row的二进制表示当前层二进制为1是冲突列,ld表示从右上角到左下角对角线冲突关系,rd表示的从左上角到右下角的冲突关系。

具体实现代码如下:

#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std; const int N = ; // 求解N皇后, N不能超过int的bits
int upper_limit = ( << N) - ; // 111...1111 n bits
int ans = ; void test(int row, int ld, int rd) {
// 如果row的皇后还没有放满
if (row != upper_limit) {
// (row|ld|rd)表示行row,右上到左下ld,左上到右下rd对角线,为1则是不能放的位置, 取~后表示能放置的位置
// 因为是用的int 32位存的,所以N位向上的高位需要重新置成0
// 所以再和upper_limit取&操作,就提取出所有可以放置皇后的位置
int pos = upper_limit & ~(row | ld | rd); // while 循环枚举所有为1的位置,然后去放置皇后
while (pos != ) {
// 和树状数组的lowbit一样,提取出pos的二进制最后一个1所在的位置的值
// 也可以写成x & (x^(x-1))
int p = pos & (-pos); pos = pos ^ p; // 将p二进制为1的位置在pos中置为0
// row | p 把p二进制为1的位置放上皇后
// (ld | p) << 1 更新ld的下一层不能放的位置
// (rd | p) >> 1 更新rd的下一层不能放的位置
test(row|p, (ld|p) << , (rd|p) >> );
}
} else ans++; } int main() {
ans = ;
clock_t start, finish;
double duration;
start = clock();
test(, , );
finish = clock();
duration = (double)(finish-start) / CLOCKS_PER_SEC;
printf("Time is %lf\n", duration);
printf("共有多少种情况: %d\n", ans);
return ;
}

分析:

位运算版本确实在代码编写和时间效率上都相当棒

代码的关键部分,就在于处理row,ld,rd搜索时候的禁位变化

当处理超过int可表示位数时候,这时候就要抛弃整型,使用bitset或者位结构去做相关操作

N皇后问题(位运算实现)的更多相关文章

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

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

  2. N皇后的位运算有感

    N皇后很明显是一个NP-Hard问题,如果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. Codeforces Round #228 (Div. 1) B

    B. Fox and Minimal path time limit per test 1 second memory limit per test 256 megabytes input stand ...

  2. Codeforces Round #228 (Div. 1) A

    A. Fox and Box Accumulation time limit per test 1 second memory limit per test 256 megabytes input s ...

  3. ORACLE-SELECT学习

    (一)select格式:SELECT [ ALL | DISTINCT ] <字段表达式1[,<字段表达式2[,…] FROM <表名1>,<表名2>[,…] [W ...

  4. Spring:No bean named 'beanScope' is defined

    初学Spring,“No bean named 'beanScope' is defined”这个问题困扰了我好几个小时,查资料无果后,重写好几遍代码后发现问题居然是配置文件不能放在包里...要放在s ...

  5. 2008server安装Intel I217V网卡驱动

    问题:由于在职的是小公司,公司服务器都是DIY的,拒绝采购品牌服务器,所以配件都是自己DIY的,这样就会出现很多兼容性问题,例如服务器主板是AUS B85-PRO-Gamer,装的是服务器系统wind ...

  6. Android开发--环境的配置

    一 Android开发环境:JDK.eclipse ADT.海马模拟器或者夜神模拟器.配置之前先保证运行内存足够大,不然会导致运行卡. 二 JDK(不用安装) 1.jdk官方下载地址:http://w ...

  7. tz2txt的安装与使用

    tz2txt是一个开源的小工具,用于把帖子的楼主发言保存为txt文件. 目前支持天涯社区.新浪论坛(大部分版块).百度贴吧. 本文介绍tz2txt的安装与使用. 本文目录: 一.下载.安装 二.使用t ...

  8. java length size

    1 java中的length属性是针对数组说的,比如说你声明了一个数组,想知道这个数组的长度则用到了length这个属性. 2 java中的length()方法是针对字符串String说的,如果想看这 ...

  9. Linux下查找文件命令——find

    find [在哪个目录下查找] -name <文件名> 1.场景:当你知道了某个文件的文件名,而不知道这个文件放到哪个文件夹,甚至是层层套嵌的文件夹里, 也可以使用find命令来查找,如: ...

  10. [转]Debug 和 Release 编译方式的区别

    本文主要包含如下内容: 1. Debug 和 Release 编译方式的本质区别 2. 哪些情况下 Release 版会出错 3. 怎样“调试” Release 版的程序 Debug 和 Releas ...