【位运算经典应用】 N皇后问题
说到位运算的经典应用,不得不说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皇后问题相关推荐
- 【面试锦囊】位运算介绍与经典例题总结
原创公众号:bigsai 原创不易,如果有收获请不要吝啬你的赞赞! 文章已收录在 全网都在关注的数据结构与算法学习仓库 欢迎star 前言 位运算隐藏在编程语言的角落中,其神秘而又强大,暗藏内力,有些 ...
- JavaScript 位运算总结拾遗
最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个 ...
- 你可能不知道的位运算技巧
作者 | bigsai 责编 | 张文 头图 | CSDN 下载自视觉中国 位运算隐藏在编程语言的角落中,其神秘而又强大,暗藏内力,有些人光听位运算的大名的心中忐忑,还有些人更是一看到位运算就远远离 ...
- 【建议收藏】面试官会问的位运算奇淫技巧
往期热门文章: 1.到底可不可以用 kill -9 关闭程序?2.IDEA 2021首个大版本发布,新增了这几个超实用功能!3.Optional 是个好东西,你真的会用么?4.Java 8 Concu ...
- 利用位运算解决 N 皇后问题
题目: LeetCode 51. N-Queens 分析: N 皇后问题是考查递归回溯的经典问题,深度优先搜索的难点在于如何剪枝,在这个问题里面的剪枝,我们需要利用额外的空间去记录当前行的有效空位,只 ...
- 洛谷P1562 还是N皇后(DFS+状态压缩+位运算)
八皇后问题的介绍在此不再赘述,只贴一下经典八皇后问题的实现代码(参考刘汝佳 <算法竞赛入门经典>) void search(int i) {if(i>n){ans++;return; ...
- n皇后 - 位运算版
n皇后问题是大家在递归里会碰到的一个经典问题.以前高中我学DFS的时候,老师首先让我看的就是八皇后. 不过这皇后的时间复杂度大家可想而知了.而接下来的位运算将这个效率重新提到一个高度. 我是以前在Ma ...
- HDU2553_N皇后_位运算DFS
题目大意:N皇后 解题思路:用位运算dfs. 代码: #include using namespace std;int tal,sum; int n;void dfs(int row,int ld,i ...
- usaco Section 1.5 Checker Challenge 最慢0.162秒0.0+n皇后问题位运算版(C语言)
今天做USACO做到Section 1.5的Checker Challenge 直接dfs之后的结果是,超时.. 百度查查才想起来就是八皇后问题.有人讲怎么利用对称性怎么怎么优化,我没仔细看 直到看到 ...
- 八皇后 深度优先 广度优先 位运算
对于八皇后问题,大家应该都不陌生,只要接触过算法的,必然都会接触到这到题.对于八皇后的问题不在此叙述,可以直接百度.对于八皇后问题的解决思路,可以直接根据题目的要求便可以得到. 总的来说,就是下一个皇 ...
最新文章
- 为什么一定要读南瓜书?
- outlook收不到html图片,急!求教高手!用outlook发送HTML格式邮件,图片不能显示是为什么...
- 人生苦短,我用Python——Life is short, You need Python
- 【译】UNIVERSAL IMAGE LOADER. PART 3---ImageLoader详解
- SpringMVC中 -- @RequestMapping的作用及用法
- Cow Bowling POJ - 3176(基础的动态规划算法)
- 前端学习(1968)vue之电商管理系统电商系统之将不同的参数挂载到数据源上
- Netcdf文件导出基本代码示例
- 90后副教授一作发Science,刷新该校历史
- Fedora/RedHat上使用Docker命令搭建Mysql服务器
- 基于D3.js实现分类多标签的Tree型结构可视化
- 易筋SpringBoot 2.1 | 第十八篇:SpringBoot的JDBC异常
- 单片机实验汇编--FlashRom读写实验
- 服务器硬盘一直亮红灯怎么回事,请问:电脑的硬盘为何一直亮着红灯?且硬盘很 – 手机爱问...
- 手机android id修改密码,苹果手机怎么设置id账号和密码或重设密码
- 五子棋c语言编程软件,C语言实现五子棋游戏
- C# 根据传入的字符串生成拼音码,包含全码和简码
- js截屏工具(html2anvas)
- css取消a标签自动换行,css中a元素放长英文字母或者数字自动换行的解决
- 【GRU时序预测】基于matlab卷积神经网络结合门控循环单元CNN-GRU时间序列预测【含Matlab源码 2287期】