#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 1000000005
using namespace std;
struct Node{
int maze[3][3]; //八数码具体情况
int h,g; //两个估价函数
int x,y; //空位的位置
int Hash; //HASH值
bool operator<(const Node n1)const{ //优先队列第一关键字为h,第二关键字为g
return h!=n1.h?h>n1.h:g>n1.g;
}
bool check(){ //判断是否合法
if(x>=0&&x<3&&y>=0&&y<3)
return true;
return false;
}
}s,u,v,tt;
int HASH[9]={1,1,2,6,24,120,720,5040,40320}; //HASH的权值
int destination=322560; //目标情况的HASH值
int vis[400000]; //判断状态已遍历,初始为-1,否则为到达这步的转向
int pre[400000]; //路径保存
int way[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; //四个方向
void debug(Node tmp){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
printf("%d ",tmp.maze[i][j]);
printf("\n");
}
printf("%d %d\n%d %d\n",tmp.x,tmp.y,tmp.g,tmp.h);
printf("hash=%d\n",tmp.Hash);
}
int get_hash(Node tmp){ //获得HASH值
int a[9],k=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
a[k++]=tmp.maze[i][j];
int res=0;
for(int i=0;i<9;i++){
int k=0;
for(int j=0;j<i;j++)
if(a[j]>a[i])
k++;
res+=HASH[i]*k;
}
return res;
}
bool isok(Node tmp){ //求出逆序对,判断是否有解
int a[9],k=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
a[k++]=tmp.maze[i][j];
int sum=0;
for(int i=0;i<9;i++)
for(int j=i+1;j<9;j++)
if(a[j]&&a[i]&&a[i]>a[j])
sum++;
return !(sum&1); //由于目标解为偶数,所以状态的逆序数为偶数才可行
}
int get_h(Node tmp){ //获得估价函数H
int ans=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
if(tmp.maze[i][j])
ans+=abs(i-(tmp.maze[i][j]-1)/3)+abs(j-(tmp.maze[i][j]-1)%3);
return ans;
}
void astar(){ //搜索
priority_queue<Node>que;
que.push(s);
while(!que.empty()){
u=que.top();
que.pop();
for(int i=0;i<4;i++){
v=u;
v.x+=way[i][0];
v.y+=way[i][1];
if(v.check()){
swap(v.maze[v.x][v.y],v.maze[u.x][u.y]); //将空位和相邻位交换
v.Hash=get_hash(v); //得到HASH值
if(vis[v.Hash]==-1&&isok(v)){ //判断是否已遍历且是否可行,后者可以不要
vis[v.Hash]=i; //保存方向
v.g++;; //已花代价+1
pre[v.Hash]=u.Hash; //保存路径
v.h=get_h(v); //得到新的估价函数H
que.push(v); //入队
}
if(v.Hash==destination)
return ;
}
}
}
}
void print(){
string ans;
ans.clear();
int nxt=destination;
while(pre[nxt]!=-1){ //从终点往起点找路径
switch(vis[nxt]){ //四个方向对应
case 0:ans+='r';break;
case 1:ans+='l';break;
case 2:ans+='d';break;
case 3:ans+='u';break;
}
nxt=pre[nxt];
}
for(int i=ans.size()-1;i>=0;i--)
putchar(ans[i]);
puts("");
}
int main(){
char str[100];
while(gets(str)!=NULL){
int k=0;
memset(vis,-1,sizeof(vis));
memset(pre,-1,sizeof(pre));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++){
if((str[k]<='9'&&str[k]>='0')||str[k]=='x'){
if(str[k]=='x'){
s.maze[i][j]=0;
s.x=i;
s.y=j;
}
else
s.maze[i][j]=str[k]-'0';
}
else
j--;
k++;
}
if(!isok(s)){ //起始状态不可行
printf("unsolvable\n");
continue;
}
s.Hash=get_hash(s);
if(s.Hash==destination){ //起始状态为目标状态
puts("");
continue;
}
vis[s.Hash]=-2;
s.g=0;s.h=get_h(s);
astar();
print();
}
return 0;
}

hdu1043的更多相关文章

  1. ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

    八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...

  2. HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)

    题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...

  3. 后缀数组:HDU1043 Longest Common Substring

    Longest Common Substring Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  4. HDU1043 Eight(BFS)

    Eight(South Central USA 1998) Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

  5. 【双向广搜+逆序数优化】【HDU1043】【八数码】

    HDU上的八数码 数据强的一B 首先:双向广搜 先处理正向搜索,再处理反向搜索,直至中途相遇 visit 和 队列都是独立的. 可以用一个过程来完成这2个操作,减少代码量.(一般还要个深度数组) 优化 ...

  6. POJ1077&&HDU1043(八数码,IDA*+曼哈顿距离)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30127   Accepted: 13108   Special ...

  7. hdu-1043 bfs+康拓展开hash

    因为是计算还原成一种局面的最短步骤,应该想到从最终局面开始做bfs,把所有能到达的情况遍历一遍,把值存下来. bfs过程中,访问过的局面的记录是此题的关键,9*9的方格在计算过程中直接存储非常占内存. ...

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

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

  9. HDU1043 Eight(八数码:逆向BFS打表+康托展开)题解

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

随机推荐

  1. 【蜗牛—漫漫IT路之大学篇(九) 】

    再来一篇叨叨的博客 近期,状态还是那个状态,人还是那个人. 前两天,感冒了,可能是宿舍阴面的事吧.然后,中午睡觉的时候穿着短袖披了一件外套,然后鼻子就不通气了.只是,前天晚上,我骑着崔国强的车子跑了不 ...

  2. Singal Page App:使用Knockout和RequireJS创建高度模块化的单页应用引擎

    Singal Page App 开篇扯淡 距离上一篇文章已经有好几个月,也不是没有时间记录点东西,主要是换了新的工作,在一家外资工作,目前的工作内容大多都是前端开发,新接触的东西因为时间原因,大多还不 ...

  3. 【MS SQL】把多个数据库合并为一个新的数据库

    原文:[MS SQL]把多个数据库合并为一个新的数据库 因应工作要求,需要把两个数据库合并成一个库: 一开始使用"导入数据.导出数据和复制数据库"三个工具时,没有达到要的效果. 后 ...

  4. Zabbix监控系统功能及基本使用

    一.Zabbix基本介绍:    zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案.它能监视各种网络参数,保证服务器系统的安全运营:并提供柔软的通知机制以让系 ...

  5. MVC 5 - 查询Details和Delete方法

    MVC 5 - 查询Details和Delete方法 在这部分教程中,接下来我们将讨论自动生成的Details和Delete方法. 查询Details和Delete方法 打开Movie控制器并查看De ...

  6. c#跟objective-c语言特性

    c#跟objective-c语言特性的对比 拿c#语言跟objective-c做个对比,记录下自己认为是差不多的东西. 学过objc的人相信对category这个东西肯定不陌生,它可以让我们在没有源码 ...

  7. ListNode线性表

    不常用,可以看一下实现原理 namespace UnilateralismChainTable { // 结点类 public class ListNode { public ListNode(int ...

  8. C#中另辟蹊径解决JSON / XML互转的问题

    C#中另辟蹊径解决JSON / XML互转的问题 最近在一个POC的项目中要用到JSON和XML的相互转换, 虽然我知道很多类库如JSON.NET具备这种功能, 但是我还是另辟蹊径的使用Spider ...

  9. [Usaco2008 Mar]River Crossing渡河问题[简单DP]

    Description Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,F ...

  10. jquery数据验证插件

    jquery数据验证插件(自制,简单,练手)   一:最近项目中js数据验证比较多,为了统一风格,移植复用,于是顺手封装了Jquery的插件. (function($) { var defaults ...