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 ...
随机推荐
- 学习神器!本机安装虚拟机,并安装Linux系统,并部署整套web系统手册(包含自动部署应用脚本,JDK,tomcat,TortoiseSVN,Mysql,maven等软件)
1. 引言 编写目的 本文档的编写目的主要是在Linux系统上部署mis_v3员工管理系统,方便测试,并为以后开发人员进行项目部署提供参考 准备工作 软件部分 软件项 版本 备注 Mysql 5. ...
- Codeforces 1153D 树形DP
题意:有一个游戏,规则如下:每个点有一个标号,为max或min, max是指这个点的值是所有子节点中值最大的那一个,min同理.问如何给这颗树的叶子节点赋值,可以让这棵树的根节点值最大. 思路:很明显 ...
- C/C++代码覆盖率工具gcov、lcov
gcov是一个可用于C/C++的代码覆盖工具,是gcc的内建工具.下面介绍一下如何利用gcov来收集代码覆盖信息. 想要用gcov收集代码覆盖信息,需要在gcc编译代码的时候加上这2个选项 “-fpr ...
- Part9---代码搬移不可少
1.回顾ARM启动流程就可知道需要执行代码搬移 2.代码搬移 1)起点:NAND FLASH,今天的起点是SRAM垫脚石.为什么?因为我们要从nandflash取搬移数据需要先对其进行初始化,二而我们 ...
- Graph cut使用方法
下载:http://www.wisdom.weizmann.ac.il/~bagon/matlab.html 1. 运行compile_gc.m 2.运行gc_example.m(必须同目录吗?!) ...
- hibernate的几个重要的类和接口
Configuration类 该类的对象会自动加载hibernate.cfg.xml文件,同时也可以定义自己的配置文件 sessionFactory接口 由于SessionFactory是重量级的,也 ...
- 【单例模式】Singleton pattern
前言:有很多时候,在一个生命周期中我们只要一个对象就可以了,比如:线程池,缓存,对话框,日志,显卡驱动等等.如果造出多个实例,就会导致许多问题产生,例如:程序的行为异常.资源使用过量,或者说不一致的结 ...
- screen工具
1.背景 系统管理员经常需要SSH 或者telent 远程登录到Linux 服务器,经常运行一些需要很长时间才能完成的任务,比如系统备份.ftp 传输等等.通常情况下我们都是为每一个这样的任务开一个远 ...
- C#Thread学习
一.Thread的使用方式 1.不带参数 (1)使用lambda public static void fun1() { Console.WriteLine($"Main ThreadId: ...
- C#多线程编程实战1.3等待线程
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...