POJ1077 Eight A*
这个题扔到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*的更多相关文章
- ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)
八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...
- POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)
思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...
- POJ1077 Eight —— 经典的搜索问题
题目链接:http://poj.org/problem?id=1077 Eight Time Limit: 1000MS Memory Limit: 65536K Total Submission ...
- poj1077 Eight【爆搜+Hash(脸题-_-b)】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298840.html ---by 墨染之樱花 题目链接:http://poj.org/pr ...
- POJ1077&&HDU1043(八数码,IDA*+曼哈顿距离)
Eight Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30127 Accepted: 13108 Special ...
- poj1077(康托展开+bfs+记忆路径)
题意:就是说,给出一个三行三列的数组,其中元素为1--8和x,例如: 1 2 3 现在,需要你把它变成:1 2 3 要的最少步数的移动方案.可以右移r,左移l,上移u,下移dx 4 6 4 5 67 ...
- poj1077
题意:给出一个八数码问题,求解法,不可解则输出unsolvable. 分析:可以用ida*算法,估价函数可以使用每个数码到其最终位置的最短距离之和.对于不可解的判断,我这里用迭代深度大于100时判定为 ...
- POJ1077 八数码 BFS
BFS 几天的超时... A*算法不会,哪天再看去了. /* 倒搜超时, 改成顺序搜超时 然后把记录路径改成只记录当前点的操作,把上次的位置记录下AC..不完整的人生啊 */ #include < ...
- POJ1077 Eight —— IDA*算法
主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html 代码一:像BFS那样,把棋盘数组放在结构体中. #include <iostream&g ...
随机推荐
- python中Dict与OrderedDict
使用dict时,Key是无序的.在对dict做迭代时,我们无法确定Key的顺序. 如果要保持Key的顺序,可以用OrderedDict: from collections import Ordered ...
- cocos2d-x 在vs2010下的环境配置
cocos2d-x编译完成之后生成了一堆动态库,在window下分别为.dll , .lib ,其中*lib是在编译的时候需要链接的,*.dll是在运行的时候依赖的.所以当我们创建一个cocos2d- ...
- datatables01 安装、数据源、选中行事件、新增一行数据、删除一行数据
1 安装 1.1 引入必要文件 要在项目中使用datatables需要引入三个文件 >DataTables CSS >jQuery >DataTables JS <!-- Da ...
- 3、python的传入参数
转载:https://blog.csdn.net/abc_12366/article/details/79627263 1.位置参数: def func(a, b): print(a+b) func( ...
- springboot-条件化注解
在项目中,有时会遇到我们的Configuration.Bean.Service等等的bean组件需要依条件按需加载的情况.那么Spring Boot怎么做的呢?它为此定义了许多有趣的条件,当我们将它们 ...
- (转)不定义JQuery插件,不要说会JQuery
原文地址:http://www.cnblogs.com/xcj26/p/3345556.html 一:导言 有些WEB开发者,会引用一个JQuery类库,然后在网页上写一写$("#" ...
- EasyUI学习笔记(1)----Tree控件实现过程中.NET下无法访问json数据的解决办法
直接调用官网的Demo中的方法 , 将json数据存储在同目录下,但是在运行之后树没有出现,用FireBug调试,错误如下 不允许访问json数据,刚开始以为是权限不够,然后又给解决方案所在的文件夹设 ...
- cmake安装方法
由于Ubuntu14.04的cmake版本为2.8.x,而如果需要cmake3.x版本时,无法生成makefile,有两种方法可以安装cmake3.10.0: 方法1: sudo apt-get in ...
- 利用Response.Buffer做类似异步效果
在page_load加入以下代码 Response.Buffer = false; //这句话非常重要 for (int i = 0; i < 10; i++) { Thread.Sleep( ...
- C#在线运行--cmd方法
此次C#在线运行采用cmd.exe用csc对文件进行编译,然后再运行的思路实现在线运行的效果.不过会生成二个文件(.cs和.exe),可能需要定期清除临时文件夹. 首先利用时间戳生成唯一文件名, ...