题目链接: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