POJ1753位压缩BFS

在很多情况下,我们可以用一个整数或者多个整数把多变的状态压缩,这样有利于空间上的优化,虽然在代码量上并不能得到多少的好处,但是遇到数据量大的时候还是可以有一定的效果的。

以POJ1753为例,这题是推荐题中的简单题了,一般的搜索完全可以过,甚至不用搜索。。。

我的方法是把BFS的状态压缩,由于每个牌面就4乘以4,也就是16个格子,每个格子只有黑白两种状态,用一个int型数就可以装下整个状态。

将牌面从上到下从左到右编号0到15,这样int型数从低位开始的第i位标记为0或者1,分别表示白色和黑色,用位运算进行状态转移。

看下我的结构体:

 

code表示这个状态中各个格子是否被翻过,对应位如果为1,则表示被按过,这种题目有一个显著的特点,那就是一个格子之多翻一次,否则和没翻是一个效果,这样我们记录了格子后就可以知道哪些格子被我们翻过,那些没有。

table表示状态牌面的情况,第i位如果为1表示这位是黑色,否则为白色。

depth表示从初状态到此状态的步数。

last表示装移到这个状态翻转的格子编号,这样,我们每次都从最后一个翻转的格子之后的格子开始搜索,不会重复搜索。

 

另外,位压缩之后,写一个状态转移函数hash(),用于转移状态。

其中table参数就是需要变换的牌面,op代表翻转的格子的编号,函数中的st变量表示需要翻转的位,如果第i位需要翻转,则这位就是1,否则为0,首先第op位一定是需要翻转的,然后四个if判断格子的位置,当格子在最左边的时候,op%4等于0,最上边的时候,op/4等于0,以此类推,当格子不是最左边的时候,要对其左边(op-1)位置的格子进行翻转,因此更新st变量第(op-1)位为1,其他的类似。

 

在BFS函数中,末状态就是15个0或者16个0((1<<16)-1),这样直接用判断整数是否相等就可以搞定。

 

主程序完整代码如下:

 

反思:这题BFS位压缩其实还可以优化,code和last的作用是一样的,因为每次都从最后翻转的那位的后一位开始搜索,不用判断code变量,可以考虑将结构体变量再去掉一个。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值