博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1562 还是N皇后
阅读量:6146 次
发布时间:2019-06-21

本文共 1218 字,大约阅读时间需要 4 分钟。

神奇的位运算啊。。。

这道题显然不能用普通的回溯法解决。我们可以使用位运算。

框架同样采用dfs,但是使用了4个东西作为参数(使用二进制):

  1. line作为当前在哪个位置已经放置了皇后(1表示已经放置,0表示可以放置)
  2. ll作为当前已放置的皇后的左上右下对角线对当前行的影响(1表示不能放置,0表示可以放置)
  3. rr作为当前已放置的皇后的右上左下对角线对当前行的影响(1表示不能放置,0表示可以放置)
  4. now作为当前dfs到了第几行(不使用二进制)

200707261.gif

200707262.gif

对于普通无限制的八皇后,直接把上面三个用二进制表示的进行或运算,然后在进行按位非(~)操作,得到的有1的就是可以放置的地方了。

这道题有限制,直接把题目给的限制一起或一下就行了。

然后运用lowbit函数可以把第一个1取出来,进行下一步的dfs。

具体参见代码,如果看不懂的可以看看这个博客:

代码:

#include
#include
const int maxn = 17;#define lowbit(x) (x & -x)int stdd[maxn];int all, n;int ans;void dfs(int i, int line, int ll, int rr){ if(i == n + 1) { ans++; return; } int may = ~(stdd[i] | line | ll | rr); may = all & may;//去掉那个左移溢出的 while(may) { int temp = lowbit(may); may -= temp; dfs(i + 1, line + temp, (ll + temp) >> 1, (rr + temp) << 1);//左上右下对角线的影响要右移,右上左下的反之 }}int main(){ scanf("%d", &n); all = (1 << n) - 1; char ch[maxn]; for(int i = 1; i <= n; i++) { scanf("%s", ch + 1); for(int j = 1; j <= n; j++) { if(ch[j] == '.') stdd[i] = stdd[i] | (1 << (j - 1));//我这里的stdd其实是与题面镜像的,但是不影响答案 } } dfs(1, 0, 0, 0); printf("%d\n", ans); return 0;}

转载于:https://www.cnblogs.com/Garen-Wang/p/9556015.html

你可能感兴趣的文章
如何避免历史回退到登录页面
查看>>
《图解HTTP》1~53Page Web网络基础 HTTP协议 HTTP报文内的HTTP信息
查看>>
unix环境高级编程-高级IO(2)
查看>>
树莓派是如何免疫 Meltdown 和 Spectre 漏洞的
查看>>
雅虎瓦片地图切片问题
查看>>
HTML 邮件链接,超链接发邮件
查看>>
HDU 5524:Subtrees
查看>>
手机端userAgent
查看>>
pip安装Mysql-python报错EnvironmentError: mysql_config not found
查看>>
http协议组成(请求状态码)
查看>>
怎样成为一个高手观后感
查看>>
[转]VC预处理指令与宏定义的妙用
查看>>
JQuery radio单选框应用
查看>>
MySql操作
查看>>
python 解析 XML文件
查看>>
MySQL 文件导入出错
查看>>
HDU2502 月之数(解法三)
查看>>
栈的压入、弹出序列 (剑指offer)
查看>>
java相关
查看>>
由一个异常开始思考springmvc参数解析
查看>>