POJ1184Clerver_Writer:广度优先搜索

本文详细介绍了如何使用广度优先搜索(BFS)解决POJ1184问题,讨论了在实现过程中遇到的重复状态判重问题,并对比了使用set和哈希表进行状态判重的两种方法。作者还分享了使用A*算法优化搜索效率的尝试,以及在不同场景下选择不同数据结构和算法的考量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 这是一道poj1184的题目,由于求解的是最优解,所以首先想到的就是使用广度优先搜索。对于这道题目我同时使用set容器,来作为状态判重。

 

代码如下:

 

在这里值得注意的地方如下:

 

1、由于重复状态的条件必须满足有相同的code和光标位置,所以在str结构体中重载operator<操作时,需要同时考虑code和pos两个域,保证这两个状态的都相同时,是不会被插入到set中的。因为对于set来说,他判断是否insert时发生冲突是通过两次使用operator<对两个状态进行检测,发现得出相同的结果。如果比较对象域是string这样的标准类型的话,那么在operator<函数中不能出现等于号,即写成这样是错误的:return a.code <= b.code,因为这样的话,就不会发生冲突了

 

2、由于没有进行其他方面的优化,所以这个程序的效率是比较差的。

 

下面是我改用hash处理状态判重的一个程序:

 

 

 

这里我把光标的位置直接放到code的最后一位,这样直接作为字符串来处理,方便很多。但是测试下来,性能没有太大的提高,因为需要搜索的状态实在太多,到后面hash冲突现象很严重。

 

后来我用A*算法来优化BFS搜索,代码如下:

 

 

这里有一些值得注意的地方:

 

1、这里关闭列表使用的是set容器,另外和传统的A*算法不同,我这里没有将产生的已有状态,但还没有进入关闭列表的状态,加入到堆数据结构中,因为可以分析出来,在这道题目中,这些状态是不可能产生更好的搜索路径的。这样大大提高了搜索效率。

但是在有些例子下,还是搜索时间太长了,需要进一步剪枝优化。

 

在这些程序中使用到的一些技巧吧:

1、使用pair这个utility。声明定义pair,如:typedef pair<set<string>::iterator , bool > Pair ;

pair的两个域可以分别用first和second来引用。

2、set容器中的insert有一个版本为 pair insert( const TYPE &val ); 注意返回的是pair。

3、string中的一个append版本为:basic_string &append( size_type num, char ch );  在字符串的末尾添加num个字符ch 。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值