【洛谷P1225】黑白棋游戏【DFS】【状压】

该博客介绍了一种解决黑白棋游戏的方法,利用16位二进制数存储状态,并通过DFS进行搜索。作者从(3,3)开始枚举,判断并交换条件,实现了状态的遍历。此外,还讨论了二维到一维转换和位运算的应用,虽然可以进一步压缩状态存储,但实现较为复杂。博主分享了调整代码的心路历程,经过休息后成功通过样例和洛谷测试。" 132285289,19671414,Java实现CRC32校验和详解,"['Java', '开发语言', '数据校验']
摘要由CSDN通过智能技术生成

在这里插入图片描述

分析

这题看到整个矩阵只有16个数,且都是0/1,所以考虑用一个16位二进制数来存整个状态。然后用一个数组就可以存所有的状态(判断是否曾经到达)

我们从(3,3)开始枚举每个点,从开始状态开始搜索。矩阵的坐标是这样设计的:

  3 2 1 0
3  
2 
1
0

每次都判断能否向下或者向右交换(数字不一样且状态没访问过),能访问就入队。记录前驱和坐标,后面递归输出。

关于二维与一维的转换和一些位运算解析:

1. pos=4*i+j;//在16位中的位置 
2. q[h]&(1<<pos)//取出第pos位
3. temp=q[h]^(3<<pos-1)//将自己和右边的交换
4. temp=q[h]^((1<<pos)+(1<<pos-4))//将自己和下面的交换
5. p1[q[t]]=(5-(i+1))*10+(5-(j+1));
   p2[q[t]]=(5-(i+1))*10+(5-(j+1)+1);//转为横纵坐标的记录

其实在存状态是否被访问的时候,还可以再压缩,现在是一个整数存一个“能或不能”,其实可以一位存一个,又压缩到1/32了,但是较难实现,我没有使用。

瞎扯淡:今天早上调了好久,下午睡一觉过来打了不到30min过了样例,很兴奋,小心翼翼又试了很多次,结果洛谷一次过,差点跳起来!

上代码

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值