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

N皇后很明显是一个NP-Hard问题,如果n足够大的话,在有限较短的时间内是很难得出答案的,但是注意到N皇后(笔者认为这类问题称为棋盘问题更为贴切),在n*n棋盘之上,每个点有且只有两种状态,这与电脑自身的进制非常类似,因此很自然的想到状态压缩,通过二进制码来表示原先通过数组来表示的皇后状态,也就是我们从原先的二维问题转换为一维问题 这边补充一些前置知识: 神奇的位运算: kk & (kk-1) : 可以将kk的二进制码的最右边的1去掉 eg: 10010 & (10010-1) = 10…
本文参考Matrix67的位运算相关的博文. 顺道列出Matrix67的位运算及其使用技巧 (一) (二) (三) (四),很不错的文章,非常值得一看. 主要就其中的N皇后问题,给出C++位运算实现版本以及注释分析. 皇后问题很经典,就不再赘述问题本身,解决皇后问题,一般采用的都是深搜DFS+回溯的方法,按照行(列)的顺序枚举每一个可以放置的情况,然后进行冲突判断,当前的放置是否合法,合法就继续搜索下一层,不合法就搜索就回溯.直到,找到一个合法的解,每一层都有一个皇后并且不发生冲突,这时候,放置…
题目描述 Description 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上. 输入描述 Input Description 给定棋盘的大小n (n ≤ 13) 输出描述 Output Description 输出整数表示有多少种放置方法. 样例输入 Sample Input 8 样例输出 Sample Output 92 数据范围…
题目链接: https://www.luogu.org/problem/show?pid=1219#sub row:受上面的皇后通过列控制的位置 ld:受上面的皇后通过从右至左的斜对角线控制的位置 rd:受上面的皇后通过从左至右的斜对角线控制的位置 upperlim:每一列都被控制时row的状况 #include <cstdio> using namespace std; ][], a[], n; void test(int row, int ld, int rd) { if (row ==…
说到位运算的经典应用,不得不说N皇后问题. 学过程序设计的都知道N皇后问题,没听过也没关系.很简单,最传统的的N皇后问题是这个样子的,给你一个n * n大小的board,让你放n个皇后(国际象棋),要满足任意两个皇后不能在一条水平线上,不能在一条垂直线上,也不能在一条45度的斜线上.听起来似乎和数独挺像,其实N皇后的条件更苛刻,除了水平垂直线外,数独只有两条对角线,而N皇后有很多条斜线,这点需要注意. 为了判断程序的正确性,正好leetcode上有道题可以测试N-Queens II,也是最经典的…
N皇后问题 时间限制: 5 Sec  内存限制: 128 MB 题目描述 魔法世界历史上曾经出现过一个伟大的罗马共和时期,出于权力平衡的目的,当时的政治理论家波利比奥斯指出:“事涉每个人的权利,绝不应该让任何权力大到压过其他力量,使他人无法立足于平等条件与之抗辩的地步.”所以,即使关押修罗王和邪狼的监狱里的每个暗势力之间的关系十分紧张,但为了维持监狱的正常秩序,如非必要,他们会尽可能地避免直接接触.这类似著名的N皇后问题,即在N×N格的国际象棋上摆放N个皇后,使其不能互相攻击,即任意两个皇后都不…
N皇后解法以及位运算优化 观察棋盘,要求皇后之间不能处在同行同列同一条斜线,求使得每行都有一个皇后的放置方法共有多少种. 每尝试放置一个皇后,都可以把该位置所在的行.列标号用一个数组标记,含义表示该行该列已经被占用,同时所在斜列也要进行标记.所在斜线有左斜线和右斜线两种,画个图解释一下. 对于左斜线(斜率为-1),假设坐标为\((x,y)\) ,我们可以用 \(k = (x-y)\) 来表示,但是可能会有负数产生不利于用数组标记,所以我们给它加个\(base = n\) (或者任何一个比n-1大…
关键位运算 x & (-x) 取得最低位1 x & (x-1) 去掉最低位1 class Solution(object): def totalNQueens(self, n): """ :type n: int :rtype: int """ if n < 1 : return [] self.count = 0 self.DFS(n,0,0,0,0) return self.count def DFS(self,n, r…
最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个数为2的幂,那么该数的二进制码只有最高位是1. 根据这个性质,我们来举个栗子,比如有数字10,转为二进制码后为: 1 0 1 0 我们只需把 0 bit的位置全部用1填充,然后再把该二进制码加1就ok了.而x | (x + 1)正好可以把最右边的0置为1,可是问题来了,当二进制码变成 1 1 1 1…
题解:首先,这道题可以用位运算来表示每一行的状态,同八皇后的搜索方法,然后对于限制条件不相互攻击,则只需将新加入的一行左右移动与上一行相&,若是0则互不攻击,方案可行.对于每种方案,则用递推来统计,将前一排所有可以的情况全部加上即可.bit数组记录每个数字二进制位中1的个数,方便计算. if(check(j,q))f[i][j][k]+=f[i-1][q][k-bit[j]]; #include <iostream> #define rep(i,n) for (int i=0;i<…