用位运算解决皇后问题以及皇后变体问题

问题描述:

N皇后问题或者如下皇后变体问题:

在一个6*6的棋盘里放置4个互不攻击的车的方案数为多少?(阿里2016实习生在线笔试题)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

int n,m,goal;
int ans,sum;

void DFS(int row,int ld,int rd,int sum,int now)
//
//每一次调用,都根据row,ld,rd计算出可行位置pos。然后遍历pos的所有位置。ld<<1,rd>>1表示下一行。row+p,表示第p行已被占用
// (ld+p)<<1,(rd+p)>>1表示第p行被占用后,在下一行对角线位置的冲突情况。
{
     if (now>n) return;
     if (sum<m)
     {                   int pos=goal&(~(row|ld|rd));//所有可行位置
                         //printf("%d %d %d %d\n",pos,row,ld,rd);
                         while (pos>0)//遍历该行所有的位置
                         {
                               int p=pos&(-pos);//p是某一个可以放置的位置 ,其实就是右边的位
                               pos-=p;
                               DFS(row+p,(ld+p)<<1,(rd+p)>>1,sum+1,now+1);
                         }
                         DFS(row,ld<<1,rd>>1,sum,now+1);//遍历下一行
     }
     else ++ans;
}

int main()
{
    scanf("%d%d",&n,&m);//n = 6,m = 4表示,在6×6棋盘上放置4个皇后
    goal=(1<<n)-1;//goal表示一行中所有的位置。
    //printf("%d\n",goal);
    DFS(0,0,0,0,0);
    printf("%d\n",ans);
    system("pause");
    return 0;
}

结果与分析:

详情见matrix67大牛的博客。

时间: 2024-09-29 06:41:02

用位运算解决皇后问题以及皇后变体问题的相关文章

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

关键位运算 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

位运算解决“一个数组中,只有一个数字出现n次,其他数字出现k次”问题

转自:https://blog.csdn.net/monster_girl/article/details/52928864 在学习完位操作后,经常会遇到一类关于查找缺失整数的问题. 第一类是给你一个数组,告诉你这些数字的范围是什么,然后让你查找这个缺失的数字(例如无序数组的范围是从1到10,不重复的9个数). 这类问题的解决方法比较多样,第一种,因为给定了范围可以通过计算数字总和值,然后分别减去这些数字,剩下的则是缺失的数字.第二种,对这个数组进行排序,遍历整个数组,然后判断相邻的元素是否连续

位运算解决多标签问题

日常开发中经常用到一个酒店下有多个标签比如酒店的风格特点有:无柱?场地方正?豪华?美食?自然采光?园林草坪?温泉?景区周边?水景?泳池?中式院落?西式装修?少数民族 会场进车?高尔夫 我们一般都会对其进行编号: { '1': 无柱, '2': 场地方正, '3': 豪华, '4': 美食, '5': 自然采光, '6': 园林草坪, '7': 温泉, '8': 景区周边, '9': 水景, '10': 泳池, '11': 中式院落, '12': 西式装修, '13': 少数民族, '14': 会

N皇后(回溯版+位运算版)

题目描述 Description 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上. 输入描述 Input Description 给定棋盘的大小n (n ≤ 13) 输出描述 Output Description 输出整数表示有多少种放置方法. 样例输入 Sample Input 8 样例输出 Sample Output 92 数据范围

位运算总结&amp;拾遗

JavaScript 位运算总结&拾遗 最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个数为2的幂,那么该数的二进制码只有最高位是1. 根据这个性质,我们来举个栗子,比如有数字10,转为二进制码后为: 1 0 1 0 我们只需把 0 bit的位置全部用1填充,然后再把该二进制码加1就ok了.而x | (x + 1)正好可以把最右边的0置为1,可是

leetcode:single-number-ii(Java位运算)

题目: Given an array of integers, every element appears three times except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 给定一个整型数组,每个数都出现了三次(只有一个数只出现了一次),找

浅谈位运算

位运算算是从汇编语言一代传下来的老东西了,只有寥寥6个运算符.乍一看,你会说它没什么用处,那么你只对了一半:站在现在的高级编程角度来讲,确实用处不大:但是在涉及硬件底层的编程(如驱动程序,嵌入式开发)里,需要很强的操纵硬件能力,这时,就常常涉及到位运算. 位运算有6个运算符,它们分别是:&(与).|(或).^(异或).~(取反).>>(右移).<<(左移).其含义如下表所示: 运算符 含义 & 按位与 | 按位或 ^ 按位异或 ~ 取反 << 左移 &g

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

本文参考Matrix67的位运算相关的博文. 顺道列出Matrix67的位运算及其使用技巧 (一) (二) (三) (四),很不错的文章,非常值得一看. 主要就其中的N皇后问题,给出C++位运算实现版本以及注释分析. 皇后问题很经典,就不再赘述问题本身,解决皇后问题,一般采用的都是深搜DFS+回溯的方法,按照行(列)的顺序枚举每一个可以放置的情况,然后进行冲突判断,当前的放置是否合法,合法就继续搜索下一层,不合法就搜索就回溯.直到,找到一个合法的解,每一层都有一个皇后并且不发生冲突,这时候,放置

皇后问题(DFS)(位运算)

皇后问题 题目描述: 有一个n*n的棋盘,你要在这个棋盘上放上n个皇后,使得她们不能相互攻击.当然为了使得问题更加有趣,我们在棋盘上限定了一些位置使得这些位置上不能放皇后. 输入格式: 第一行两个数n和m ,表示在一个n*n的棋盘上放n个皇后,有m个受限位置. 接下来m行每行两个数,x和y,表示第x行,第y列这个位置不可以放皇后. 输出格式: 一行一个数 ans,表示总的方案数. 样例输入: 4 1 1 2 样例输出: 1 朴素算法(60分) #include<iostream> using