[洛谷/题目] P1562 还是N皇后
2024-10-21 12:56:33
声明
关于科学道理都会放进代码中,但是我们需要先了解一下位运算解这道题目的基础知识
我不是很会专业词语,所以仅介绍原理
位运算基础
众所周知,二进制是0和1
2^3 | 2^2 | 2^1 | 2^0 |
---|---|---|---|
8 | 4 | 2 | 1 |
0 | 1 | 0 | 1 |
对应的,加出来就是5,这就是二进制转换,我利用二进制里的0和1来记录是否走过或者其他的yes/no的数据,和bool数组一样
和bool数组相比,二进制虽然位数有限,但是非常方便,很多事情不需要人为的去干.
比如将bool数组的false的部分找出来,合并两个数组之类的.非常浪费精力
怎么单独更改一位呢?
这里有一个例子:
9: 1001
2: 0010
2 + 9 = 11
2 | 9 = 11
11: 1011
代码里有一个lowbit函数
这是怎么获取最后一个为1的那一位所表示的的数值呢?
这里有一个例子,具体是关于反码与补码的:
9: 1001
-9: 0111
9&(-9) = 1
1: 0001
"理论存在,实践开始"
#include <iostream>
using namespace std;
// n:棋盘格数 ans:答案个数 all:全部位数为1的二进制,是一个工具变量
int n, ans, all;
// row:每一行默认的棋盘 (全局默认清空,但是赋值更保险(好习惯)
int row[20] = {};
// 返回最后一个为1的那一位所表示的的数值
int lowbit(int x) {
return x & (-x);
}
// d:当前第几行,从0开始 col:存储列是否用过 lv:存储左对角线是否用过 rv:存储右对角线是否用过
void dfs(int d, int col, int lv, int rv){
if(d == n) {
// 能走到最后一步就记录次数
ans++;
return ;
}
// 用位运算来获取遍历的依据 别忘了row是从1开始的
int vis = all & (~(row[d + 1] | col | lv | rv));
// 简单遍历
for(int i = vis; i; i -= lowbit(i)) {
int x = lowbit(i);
// 下一步 为了适应行数的+1,对角线就要对应的左移或者右移
dfs(d + 1, col + x, (lv + x) >> 1, (rv + x) << 1);
}
}
int main(){
// 零时变量,获取字符用
char t;
// 获取棋盘行列个数
cin >> n;
// 初始化为所有位数为1
all = (1 << n) - 1;
// 二位获取棋盘
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
cin >> t;
// 点为不能走(禁区)
if(t == '.') {
// 单独一行一列对应一个字节,更改即可
// 加等于也是没有问题的
row[i] |= (1<<(n - j));
}
}
}
// 开始深搜 0的所有位都为0
dfs(0, 0, 0, 0);
// 换行好习惯
cout << ans << endl;
return 0;
}
总结
题目很好,可以锻炼思维,突破传统的思维方式,打开一个新世界的大门
好久没有写过markdown,生疏了
哦吼吼,能看到这个链接就说明我的文章被爬虫爬了
请尊重原作者: https://www.cnblogs.com/dffxd/
小学四五年级可以学习到s组就是一个畸形的教育体系的体现,等国家发展起来了,吃枣药丸
最新文章
- [转]webpack进阶构建项目(一)
- How to raise exceptions in Delphi
- ACM 取石子(七)
- Redis__WindowsServer主从服务部署及调用实例
- DateTimePicker 控件的格式设置
- cocos2d menu菜单类
- JavaScript判断IE各版本最完美解决方案
- 0c-33-@class,循环retain
- angularJS随笔
- RSA 非对称加密 数字签名 数字证书
- IE6多出一只猪的经典bug
- python模块介绍- xlwt 创建xls文件(excel)
- 高可用系列之Nginx
- MySQL数据库主从分离的配置方法
- django信号浅谈
- 记自己在mybatis中设置jdbcType的一个坑
- LOJ #2142. 「SHOI2017」相逢是问候(欧拉函数 + 线段树)
- px2rem
- xamarin android 报错 Could not load assembly &#39;Xamarin.Android.Support.v7.AppCompat
- C#WinForm应用程序中嵌入ECharts图表
热门文章
- 【分析笔记】Linux tasklet 机制的理解
- 合肥光源纵向震荡数据源相关PV
- 滴水2.c++构造 与 继承
- 下篇 | 使用 &#129303; Transformers 进行概率时间序列预测
- 在 CentOS7 部署 ELK8.0.1
- Shapefile导入Oracle
- 基于Ubuntu搭建OpenGL开发环境
- PostgreSQL cache lookup failed for type XXXX 错误
- Educational Codeforces Round 137 (Rated for Div. 2) - D. Problem with Random Tests
- cisco恢复IOS文件的方法