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 ...
随机推荐
- selenium2 定位 窗体切换等等 (二)
定位用的html素材有两个 demo.html <html> <head> <title>UI Automation Testing</title> & ...
- SqlServer try catch 捕获不到的一些错误及解决方法
IF (OBJECT_ID('AA','U') IS NOT NULL) DROP TABLE AA CREATE TABLE AA(ID INT) SELECT * FROM AA --注:数据库当 ...
- nginx+django+uwsgi
最近来了兴致,想搞一下django开发,so, 搭建一下环境 1.安装django,可能通过pip install 或者源码安装(因为环境是python2.6.6的环境,所以这里采用django 1 ...
- Solidity oraclize query apikey加密
solidity 程序中如果用到oraclize query,api调用需要apikey,则最好加密apikey,否则公开solidity代码时会连同apikey一起公开. 加密方法: https:/ ...
- java中的监听事件
java监听器实现的类 1.ServletContextListener:对servlet上下文的创建和销毁监听 2.ServletContextAttributeListener:监听servlet ...
- Why does my Authorize Attribute not work?
the roles of a ClaimsPrincipal are actually just claims create with a type of ClaimsIdentity.RoleCla ...
- numpy.loadtxt() 出现codecError_____ Excel 做矩阵乘法
1) 用 numpy读入csv文件是报错 UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal m ...
- Python基础入门-For循环
For循环的功能比较强大,他可以帮助我们实现很多重复性的工作.而且for循环能迭代不同的数据结构.他的应用也十分的广泛,作为初学者,我们需要对循环的概念多加理解和练习.接下来我们就来学习for循环的一 ...
- 开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别(转)
因CooCox用户数及影响力越来越大,CooCox团队也逐渐提高了对软件及代码协议的重视.在收集整理的过程中,一些归纳好的信息和大家分享一下.首先借用有心人士的一张相当直观清晰的图来划分各种协议:开源 ...
- eclipse导入tomcat
官网下载tomcat压缩包 官网:http://tomcat.apache.org/ tomcat8:链接:http://pan.baidu.com/s/1kVHAEoR 密码:kyt8 tomcat ...