HDU(3567):八数码问题(升级版)——双BFS

这篇博客主要介绍了一种解决HDU 3567八数码问题的方法,采用双向BFS策略来确保找到最小字典序的解。作者在实现过程中遇到了几次错误,包括输出错误、路径打印顺序以及处理已遍历节点的操作。经过修正,最终AC,但时间效率与高手仍有差距。代码实现中提到,有人使用单个队列完成同样功能。
摘要由CSDN通过智能技术生成

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3567

 

有了HDU 1043的基础,此题就变得比较容易了,如果用A*算法,感觉路径不太好打印,所以就放弃了,看到有一种好像和1043一样的打表法,但是没怎么能理解,也就放弃了,虽然要打印最小字典序,单向BFS显然会TLE,所以我只能用双向BFS了。

 

好在,此题的输入保证有解,否则还得用一下八数码的逆序数定理进行判断是否有解,即:逆序数相同则有解,否则无解。

 

整体代码和1043的差不多,只是把路径的打印处理一下。虽然看似简单,但还是,WA了好多次。

第一次WA,发现了操作为0是的输出有错误。

第二次WA,发现了要想打印最小字典序,只能由正向BFS输出,即使反向遍历是出现了路径

第三次WA,发现了在方向遍历时,某个点如果已经被反向遍历,不能不对其操作,还得进行一次比较操作,看其是否是最小的字典序

主要是这三次,后来就AC了,时间1.3s,和大神的差距不小。

 

双向BFS代码:

(看到有的人用的是一个队列,代码看起来简单些,但原理是一样的,顺便附上数据生成代码)

 

 

#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>

using namespace std;

int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
int vis1[363000],vis2[363000];
int ed[]={1,2,3,4,5,6,7,8,0};
string path[363000];//记录路径

int cantor(int s[]){//康托展开,进行状态压缩
    int sum=0;
    for(in
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值