说到位运算的经典应用,不得不说N皇后问题。

学过程序设计的都知道N皇后问题,没听过也没关系。很简单,最传统的的N皇后问题是这个样子的,给你一个n * n大小的board,让你放n个皇后(国际象棋),要满足任意两个皇后不能在一条水平线上,不能在一条垂直线上,也不能在一条45度的斜线上。听起来似乎和数独挺像,其实N皇后的条件更苛刻,除了水平垂直线外,数独只有两条对角线,而N皇后有很多条斜线,这点需要注意。

为了判断程序的正确性,正好leetcode上有道题可以测试N-Queens II,也是最经典的N皇后问题,给出n求得摆法的数量。

常规解法


一个很显而易见的解法是递归求解,从上到下一行一行摆下去,并且记录每行摆的位置,因为下一行摆放的位置要根据上面的摆放情况来确定。这里我们定义了一个pos数组,pos[1]的值表示摆在第一行的皇后所在的列,pos[2]的值表示摆在第二行的皇后所在的列,以此类推,所以摆到第n行时,上面摆放的皇后的位置就可以很容易地得到,从而可以进行判断(该行什么位置可以摆放)。

当摆放到第r行时,我们遍历该行所有的n个位置,判断每个位置(r行c列)是否可以摆放,需要与前面摆放的每个皇后比较,是否在一条水平线上(这是不可能的),是否在一条垂直线上,是否在一条斜线上:

function check(r, c) {for (var i = 1; i < r; i++) {if (Math.abs(i - r) === Math.abs(pos[i] - c)) // 一条斜线上return true;if (c === pos[i]) // 一条竖直线上return true;}return false;
}

整个代码也就显而易见了:

var pos;function check(r, c) {for (var i = 1; i < r; i++) {if (Math.abs(i - r) === Math.abs(pos[i] - c)) // 一条斜线上return true;if (c === pos[i]) // 一条竖直线上return true;}return false;
}function dfs(r, n) {if (r === n + 1)return 1;var ans = 0;for (var i = 1; i <= n; i++) {if (check(r, i)) continue;pos[r] = i;ans += dfs(r + 1, n);}return ans;
}var totalNQueens = function(n) {pos = [];return dfs(1, n);
};

位运算解法


在读下文前,请先阅读【位运算经典应用】标志位与掩码会事半功倍。

位运算解法,递归是避免不了的,能优化的在于check()函数部分。

假设一个4 * 4的board,我们在第一行第三列上摆了个皇后,其实它已经把第一行之后的6个位置给ko掉了:

- - o -
- X X X
X - X -
- - X -

我们用flag=2(1<<2)记录第一行摆下的这个位置,在第二行中,很显然(1<<2)这个位置已经不能摆了,而(2<<1)这个位置也不能摆,(2>>1)这个位置也不能摆。如果要在第二行右起第1个摆下皇后,我们用flag2=1(1<<1)记录这个决定,我们只需用flag2和以上算出来的不能摆的位置去做个与运算,看看有没有冲突即可。结果(2>>1)&(1<<1)得到了非0的数,表示两者冲突,所以该位置摆放失败。

假设我们接着在第二行左起第一个摆放了皇后,对于第三行的摆放来说,第一行摆的皇后对它还是有影响的,比如它不能摆在第三行左起第一个位置,因为(2<<2)&(1<<4)!==0,冲突。而(2<<2)正是在第二排摆放决策中(2<<1)<<1。看到这里你也许应该有了思路,没错,我们可以维护三个数,l, r, c, 用来表示该行被右上角斜线,左上角斜线,正上方直线所影响而不能摆放的位置。三个数每次与欲摆放的位置作与运算,求解是否冲突,如没有,l和r分别左移右移后继续递归。

function dfs(l, r, c, index, n) {if (index === n) return 1;var ans = 0;for (var i = 0; i < n; i++) {var tmp = 1 << i;if ((tmp & l) || (tmp & r) || (tmp & c)) continue;ans += dfs((tmp | l) << 1, (tmp | r) >> 1, tmp | c, index + 1, n);}return ans;
}var totalNQueens = function(n) {return dfs(0, 0, 0, 0, n);
};

【位运算经典应用】 N皇后问题相关推荐

  1. 【面试锦囊】位运算介绍与经典例题总结

    原创公众号:bigsai 原创不易,如果有收获请不要吝啬你的赞赞! 文章已收录在 全网都在关注的数据结构与算法学习仓库 欢迎star 前言 位运算隐藏在编程语言的角落中,其神秘而又强大,暗藏内力,有些 ...

  2. JavaScript 位运算总结拾遗

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

  3. 你可能不知道的位运算技巧

    作者 | bigsai  责编 | 张文 头图 | CSDN 下载自视觉中国 位运算隐藏在编程语言的角落中,其神秘而又强大,暗藏内力,有些人光听位运算的大名的心中忐忑,还有些人更是一看到位运算就远远离 ...

  4. 【建议收藏】面试官会问的位运算奇淫技巧

    往期热门文章: 1.到底可不可以用 kill -9 关闭程序?2.IDEA 2021首个大版本发布,新增了这几个超实用功能!3.Optional 是个好东西,你真的会用么?4.Java 8 Concu ...

  5. 利用位运算解决 N 皇后问题

    题目: LeetCode 51. N-Queens 分析: N 皇后问题是考查递归回溯的经典问题,深度优先搜索的难点在于如何剪枝,在这个问题里面的剪枝,我们需要利用额外的空间去记录当前行的有效空位,只 ...

  6. 洛谷P1562 还是N皇后(DFS+状态压缩+位运算)

    八皇后问题的介绍在此不再赘述,只贴一下经典八皇后问题的实现代码(参考刘汝佳 <算法竞赛入门经典>) void search(int i) {if(i>n){ans++;return; ...

  7. n皇后 - 位运算版

    n皇后问题是大家在递归里会碰到的一个经典问题.以前高中我学DFS的时候,老师首先让我看的就是八皇后. 不过这皇后的时间复杂度大家可想而知了.而接下来的位运算将这个效率重新提到一个高度. 我是以前在Ma ...

  8. HDU2553_N皇后_位运算DFS

    题目大意:N皇后 解题思路:用位运算dfs. 代码: #include using namespace std;int tal,sum; int n;void dfs(int row,int ld,i ...

  9. usaco Section 1.5 Checker Challenge 最慢0.162秒0.0+n皇后问题位运算版(C语言)

    今天做USACO做到Section 1.5的Checker Challenge 直接dfs之后的结果是,超时.. 百度查查才想起来就是八皇后问题.有人讲怎么利用对称性怎么怎么优化,我没仔细看 直到看到 ...

  10. 八皇后 深度优先 广度优先 位运算

    对于八皇后问题,大家应该都不陌生,只要接触过算法的,必然都会接触到这到题.对于八皇后的问题不在此叙述,可以直接百度.对于八皇后问题的解决思路,可以直接根据题目的要求便可以得到. 总的来说,就是下一个皇 ...

最新文章

  1. 为什么一定要读南瓜书?
  2. outlook收不到html图片,急!求教高手!用outlook发送HTML格式邮件,图片不能显示是为什么...
  3. 人生苦短,我用Python——Life is short, You need Python
  4. 【译】UNIVERSAL IMAGE LOADER. PART 3---ImageLoader详解
  5. SpringMVC中 -- @RequestMapping的作用及用法
  6. Cow Bowling POJ - 3176(基础的动态规划算法)
  7. 前端学习(1968)vue之电商管理系统电商系统之将不同的参数挂载到数据源上
  8. Netcdf文件导出基本代码示例
  9. 90后副教授一作发Science,刷新该校历史
  10. Fedora/RedHat上使用Docker命令搭建Mysql服务器
  11. 基于D3.js实现分类多标签的Tree型结构可视化
  12. 易筋SpringBoot 2.1 | 第十八篇:SpringBoot的JDBC异常
  13. 单片机实验汇编--FlashRom读写实验
  14. 服务器硬盘一直亮红灯怎么回事,请问:电脑的硬盘为何一直亮着红灯?且硬盘很 – 手机爱问...
  15. 手机android id修改密码,苹果手机怎么设置id账号和密码或重设密码
  16. 五子棋c语言编程软件,C语言实现五子棋游戏
  17. C# 根据传入的字符串生成拼音码,包含全码和简码
  18. js截屏工具(html2anvas)
  19. css取消a标签自动换行,css中a元素放长英文字母或者数字自动换行的解决
  20. 【GRU时序预测】基于matlab卷积神经网络结合门控循环单元CNN-GRU时间序列预测【含Matlab源码 2287期】

热门文章

  1. RMI:Java中的分布式计算框架
  2. 扫地机器人湿地_黑五好价 美亚直邮 iRobot Braava 380t 拖地机器人
  3. 鸿蒙冰心有其他途径得到吗,关索除了人遁礼包,还有其他途径能获得吗?
  4. git 合并其他分支代码到自己的分支
  5. 关于VM安装Linux系统成功后无法连接WIFI
  6. PTA 程序设计天梯赛(101~120题)
  7. Android ViewPager 滑动监听事件
  8. 【安装包】PhpStorm-2018.1
  9. 洛谷 3959 宝藏——枚举+状压dp
  10. javascript简介和基本语法