这个题扔到A*可也还行。。。


定义估价函数h():为每个数或空格的位置 到 最终状态中所在位置 的 曼哈顿距离 的 总和。

把状态压成一个九进制数,便于存储和判重。

然后记录方案可以记录一下此次的操作和上一次的状态,具体见代码。

安利一篇博文:http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 。。。被震惊。。。我只会map,懒得哈希QWQ

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#include<algorithm>
#define R register int
const int dx[]={-,,,},dy[]={,,,-},end=;
const int py[]={,,,,,,,},px[]={,,,,,,,};
const char op[]={'u','r','d','l'};
using namespace std;
inline int g() {
R ret=; register char ch; while(!isdigit(ch=getchar()));
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret;
}
struct node{ int sta,g,h; node() {}
node(int ss,int gg,int hh) {sta=ss,g=gg,h=hh;}
bool operator <(const node& y) const {return g+h>y.g+y.h;}
}; int a[][];
map<int,int> d,pre,dir;
priority_queue<node> q;
inline bool ckpos(int x,int y) {return x<||x>||y<||y>;}
inline int calc(int p[][]) { R ret=;
for(R i=;i<;++i) for(R j=;j<;++j) ret=ret*+p[i][j]; return ret;
}
inline pair<int,int> recalc(int vl,int p[][]) { R x,y;
for(R i=;i>=;--i) for(R j=;j>=;--j) {
p[i][j]=vl%,vl/=; if(p[i][j]==) x=i,y=j;
} return make_pair(x,y);
}
inline int h(int p[][]) { R ret=;
for(R i=;i<;++i) for(R j=;j<;++j) {
if(p[i][j]==) continue;
ret+=abs(i-px[p[i][j]-])+abs(j-py[p[i][j]-]);
} return ret;
}
inline int Astar() {
d.clear(),pre.clear(),dir.clear();
while(q.size()) q.pop(); R st=calc(a); d[st]=;
q.push(node(st,,h(a)));
while(q.size()) {
node u=q.top(); R crt=q.top().sta; q.pop();
if(crt==end) return u.g;
R a[][]; register pair<int,int> blk=recalc(crt,a); R x=blk.first,y=blk.second;
for(R i=;i<;++i) { R xx=x+dx[i],yy=y+dy[i];
if(ckpos(xx,yy)) continue; swap(a[x][y],a[xx][yy]);
R nxt=calc(a); if(d.find(nxt)==d.end()||d[nxt]>d[crt]+)
d[nxt]=d[crt]+,pre[nxt]=crt,dir[nxt]=i,q.push(node(nxt,d[nxt],h(a)));//此处存了nxt的上一个状态和如何操作
swap(a[xx][yy],a[x][y]);
}
} return -;
}
inline void print(int s) {
if(pre.find(s)==pre.end()) return;
print(pre[s]); putchar(op[dir[s]]);
}
signed main() {
for(R i=;i<;++i) for(R j=;j<;++j) { register char ch;
while(!isdigit(ch=getchar())&&ch!='x');
if(ch=='x') a[i][j]=;
else a[i][j]=ch^;
} R ans=Astar(); if(ans==-) printf("unsolvable"),putchar('\n'); else print(end);
}

2019.04.27

POJ1077 Eight A*的更多相关文章

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

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

  2. POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)

    思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...

  3. POJ1077 Eight —— 经典的搜索问题

    题目链接:http://poj.org/problem?id=1077 Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submission ...

  4. poj1077 Eight【爆搜+Hash(脸题-_-b)】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298840.html   ---by 墨染之樱花 题目链接:http://poj.org/pr ...

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

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

  6. poj1077(康托展开+bfs+记忆路径)

    题意:就是说,给出一个三行三列的数组,其中元素为1--8和x,例如: 1 2 3 现在,需要你把它变成:1 2 3 要的最少步数的移动方案.可以右移r,左移l,上移u,下移dx 4 6 4 5 67 ...

  7. poj1077

    题意:给出一个八数码问题,求解法,不可解则输出unsolvable. 分析:可以用ida*算法,估价函数可以使用每个数码到其最终位置的最短距离之和.对于不可解的判断,我这里用迭代深度大于100时判定为 ...

  8. POJ1077 八数码 BFS

    BFS 几天的超时... A*算法不会,哪天再看去了. /* 倒搜超时, 改成顺序搜超时 然后把记录路径改成只记录当前点的操作,把上次的位置记录下AC..不完整的人生啊 */ #include < ...

  9. POJ1077 Eight —— IDA*算法

    主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html 代码一:像BFS那样,把棋盘数组放在结构体中. #include <iostream&g ...

随机推荐

  1. bootstrap中的data-dismiss属性

    <button type="button" class="btn default" data-dismiss="modal">关 ...

  2. SpringBoot20 集成SpringSecurity02 -> 利用SpringSecurity进行前后端分离的登录验证

    1 SpirngBoot环境搭建 创建一个SpringBoot项目即可,详情参见三少的相关博文 参考博文 -> 点击前往 SpirngBoot项目脚手架 -> 点击前往 2 引入Spirn ...

  3. Chrome OS上可运行Linux

    说起Chrome OS,可能多数人第一时间联想的不是操作系统,而是在浏览器领域颇为流行的谷歌Chrome浏览器.其实,Chrome OS也是谷歌 旗下的一款产品,是一款Google开发的基于Linux ...

  4. CountDownLatch、信号量

    countDownlatch可以阻塞线程,可以在某种条件下继续执行 不安全的:

  5. 框架和cms区别

    cms:精装房,拎包即可入住 框架:毛坯房,内部装修可根据自己需求来 选择策略:个性化需求不高的话,可以选择cms

  6. 利用AdaBoost方法构建多个弱分类器进行分类

    1.AdaBoost 思想 补充:这里的若分类器之间有比较强的依赖关系;对于若依赖关系的分类器一般使用Bagging的方法 弱分类器是指分类效果要比随机猜测效果略好的分类器,我们可以通过构建多个弱分类 ...

  7. Java学习——JSTL标签与EL表达式之间的微妙关系

    原文总结的太好了,忍不住记录.转发. 原文地址:http://blog.csdn.net/u010168160/article/details/49182867 目录(?)[-] 一EL表达式 EL相 ...

  8. ICallbackEventHandler使用

    后端:页面需继承ICallbackEventHandler protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack ...

  9. vs 2017局域网内调试

    之前调试代码都是在本地启动服务,以  localhost:端口号   的形式调试,今天发现也是可以用ip地址的形式来调用接口,这种方式可以支持内网内Client端调用接口,实现调试的功能,具体方法如下 ...

  10. mysql 按照姓氏排序

    1.如果是gbk存储 order by name asc 2.非GBK order by convert(name using gbk) asc