http://acm.hdu.edu.cn/showproblem.php?pid=3567

相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过,而且也不好控制字典序

换个角度想,虽然起始状态有很多,但是到底哪一位是1,哪一位是2不是最重要的,最重要的是和目标状态对应,所以可以把起始状态重新编码为"12345678"这种形式(先不考虑X),然后目标状态也对应过去,当考虑X的时候,我们可以认为起始状态只有9种,分别是'X'在各个位置的情况

利用bfs可以得到每种起始状态到对应的能够达到的所有目标状态的最短最小字典序转移方法,如果对每个状态都记录一个字符串肯定会MLE,所以只需要记录上一个状态到这一个状态转移所需要的操作即可

最后,对于每个目标状态,逆向推出状态转移序列,然后逆着输出即可

ps:一次处理3.6e6个状态,如果不用queue或者循环数组会MLE,如果不用g++提交而用c++提交会TLE

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cctype>
using namespace std;
const int base[9]={1,1,2,6,24,120,720,5040,40320};
const int dx[4]={1,0,0,-1};/转移方向,遵从字典序最小
const int dy[4]={0,-1,1,0};
const int maxh=362880;//每种开始状态所对应状态数
int des;//用于存储目标状态hash值,判断是否不需要转移
struct pnt{
int maz[3][3];
int ind;//标记起始状态的编号
int x,y;
int hashCode;
pnt(){
x=y=hashCode=-1;
}
pnt(char * str){
for(int i=0;i<9;i++){
if(str[i]=='X'){
maz[i/3][i%3]=9;
x=i/3;
y=i%3;
ind=i;
}
else maz[i/3][i%3]=str[i]-'0';
}
}
int gethashcode(){
int ans=0;
for(int i=0;i<9;i++){
int cnt=0;
for(int j=0;j<i;j++){
if(maz[j/3][j%3]>maz[i/3][i%3]){
cnt++;
}
}
ans+=base[i]*cnt;
}
return hashCode=ind*maxh+ans;
}
};
bool in(int tx,int ty){
return tx>=0&&tx<3&&ty>=0&&ty<3;
} int vis[maxh*10+1];//用于存储某状态是否已被遍历,并存储由何种操作得到该状态
int pre[maxh*10+1];//用于存储某状态由何种状态转移得到
queue<pnt> que;
char ans[maxh*10+1];//存储答案的逆序
char buff[300];//存储输入
pnt s,e;
int ind[10],indlen;//用于重新编码
bool input(){
if(scanf("%s",buff)!=1)return false;
indlen=0;//重新编码
for(int i=0;i<9;i++){
if(buff[i]>='0'&&buff[i]<='9'){
s.maz[i/3][i%3]=++indlen;
ind[buff[i]-'0']=indlen;
}
else{
s.maz[i/3][i%3]=9;
s.x=i/3;
s.y=i%3;
s.ind=i;
}
}
if(scanf("%s",buff)!=1)return false;
for(int i=0;i<9;i++){
if(buff[i]>='0'&&buff[i]<='9'){
e.maz[i/3][i%3]=ind[buff[i]-'0'];
}
else{
e.maz[i/3][i%3]=9;
e.x=i/3;
e.y=i%3;
}
}
e.ind=s.ind;//起始状态相同
des=e.gethashcode();
return true;
}
void bfs(){
while(!que.empty()){
pnt tp=que.front();que.pop();
int x=tp.x,y=tp.y;
for(int i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(in(tx,ty)){
pnt nw=tp;
swap(nw.maz[tx][ty],nw.maz[x][y]);
nw.x=tx,nw.y=ty;
if(vis[nw.gethashcode()]==-1){
vis[nw.hashCode]=i;
pre[nw.hashCode]=tp.gethashcode();
que.push(nw);
}
}
}
}
}
void init(){
memset(vis,-1,sizeof(vis));
memset(pre,-1,sizeof(pre));
pnt s1=pnt("12345678X");//9种起始状态加入序列
vis[s1.gethashcode()]=-2;
que.push(s1);
pnt s2=pnt("1234567X8");
vis[s2.gethashcode()]=-2;
que.push(s2);
pnt s3=pnt("123456X78");
vis[s3.gethashcode()]=-2;
que.push(s3);
pnt s4=pnt("12345X678");
vis[s4.gethashcode()]=-2;
que.push(s4);
pnt s5=pnt("1234X5678");
vis[s5.gethashcode()]=-2;
que.push(s5);
pnt s6=pnt("123X45678");
vis[s6.gethashcode()]=-2;
que.push(s6);
pnt s7=pnt("12X345678");
vis[s7.gethashcode()]=-2;
que.push(s7);
pnt s8=pnt("1X2345678");
vis[s8.gethashcode()]=-2;
que.push(s8);
pnt s9=pnt("X12345678");
vis[s9.gethashcode()]=-2;
que.push(s9);
bfs();
}
int heap[maxh],sz;
int getans(pnt e){//逆序遍历
sz=0;
int last=e.gethashcode();
while(pre[last]>=0){
heap[sz++]=vis[last];
last=pre[last];
}
return sz;
}
void print(){
for(int i=sz-1;i>=0;i--){
switch(heap[i]){
case 0:
putchar('d');break;
case 1:
putchar('l');break;
case 2:
putchar('r');break;
case 3:
putchar('u');break;
}
}
putchar('\n');
}
int main(){
int T;
scanf("%d",&T);
init();
for(int ti=1;ti<=T;ti++){
input();
s.hashCode=s.gethashcode();
if(s.hashCode==des){
printf("Case %d: 0\n",ti);
puts("");
continue;
}
vis[s.hashCode]=-2;
int step=getans(e);
printf("Case %d: %d\n",ti,step);
print();
}
return 0;
}

  

HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3的更多相关文章

  1. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  2. HDU 1043 & POJ 1077 Eight(康托展开+BFS | IDA*)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  3. HDU 3567 Eight II(八数码 II)

    HDU 3567 Eight II(八数码 II) /65536 K (Java/Others)   Problem Description - 题目描述 Eight-puzzle, which is ...

  4. HDU 1043 Eight(反向BFS+打表+康托展开)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目大意:传统八数码问题 解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各 ...

  5. HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二

    类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...

  6. [HDOJ1043]Eight(康托展开 BFS 打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 八数码问题,因为固定了位置所以以目标位置开始搜索,把所有情况(相当于一个排列)都记录下来,用康托 ...

  7. hdu-1043(八数码+bfs打表+康托展开)

    参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...

  8. HDU1430 BFS + 打表 + 康托展开

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 , 一道比较好的题. 这道题要用到很多知识,康托展开.BFS.打表的预处理还要用到一一映射,做完 ...

  9. HDU 1430 魔板(康托展开+BFS+预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

随机推荐

  1. JavaScript的严格模式

    js除了在普通的常规模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode).严格模式支持IE9+ Chrome FireFox 等主流浏览器. ...

  2. android MTK驱动背光唤醒流程

    在标准的android驱动中,睡眠唤醒流程非常清晰,能够较方便的更改lcd唤醒时间和led背光的点亮时间,但是也很容易出现问题,比如说闪屏,唤醒慢! 出现闪屏有两个原因 1. 开背光时间在唤醒lcd前 ...

  3. Python学习(22)python网络编程

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

  4. jquery ajax 实例

    $(function(){ $.ajax( { url:'{:U('shenhe')}',// 跳转到 action data:{ }, type:'post', cache:false, dataT ...

  5. CentOS用yum快速安装nginx

    增加nginx源 vim  /etc/yum.repos.d/nginx.repo [nginx] name=nginx repo baseurl=http://nginx.org/packages/ ...

  6. linux 通过 ulimit 改善系统性能

    https://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/ 概述 系统性能一直是一个受关注的话题,如何通过最简单的设置来实现最有效的性能调优,如何 ...

  7. Linux下的split 命令(将一个大文件根据行数平均分成若干个小文件)

    将一个大文件分成若干个小文件方法 例如将一个BLM.txt文件分成前缀为 BLM_ 的1000个小文件,后缀为系数形式,且后缀为4位数字形式 先利用 wc -l BLM.txt       读出 BL ...

  8. ssh批量登录并执行命令(python实现)

    局域网内有一百多台电脑,全部都是linux操作系统,所有电脑配置相同,系统完全相同(包括用户名和密码),ip地址是自动分配的.现在有个任务是在这些电脑上执行某些命令,者说进行某些操作,比如安装某些软件 ...

  9. J2EE 第二阶段项目(八)

    类别统计差不多完成了! 还有个地区统计了!

  10. Oracle SQL 调优之 sqlhc

    SQL 执行慢,如何 快速准确的优化. sqlhc 就是其中最好工具之一 通过获得sql所有的执行计划,列出实际的性能的瓶颈点,列出 sql 所在的表上的行数,每一列的数据和分布,现有的索引,sql ...