主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html

关于A*算法:g(n)表示从起点到任意节点n的路径花费,h(n)表示从节点n到目标节点路径花费的估计值(启发值),f(n) = g(n)+h(n)。
A*算法必须满足的条件(能不能满足由所选的h(n)估计方式决定):每次扩展的节点的 f 值 >= 父节点的 f 值。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e6+;
#define AIM 1 //123456789的哈希值为1 struct node
{
int status;
int s[];
int loc;
int g,h,f;
bool operator<(const node x)const{
return f>x.f;
}
}; int vis[MAXN], fac[] = { , , , , , , , , };
int dir[][] = { -,, ,, ,-, , };
char op[] = {'u', 'd', 'l', 'r' };
char path[MAXN];
int pre[MAXN]; int cantor(int s[]) //获得哈希函数值
{
int sum = ;
for(int i = ; i<; i++)
{
int num = ;
for(int j = i+; j<; j++)
if(s[j]<s[i])
num++;
sum += num*fac[-i];
}
return sum+;
} int dis_h(int s[]) //获得曼哈顿距离
{
int dis = ;
for(int i = ; i<; i++)
if(s[i]!=) //‘x’不能算进去,否则不能满足:“每次扩展的节点的 f 值 >= 父节点的 f 值小”
{
int x = i/, y = i%;
int xx = (s[i]-)/, yy = (s[i]-)%;
dis += abs(x-xx) + abs(y-yy);
}
return dis;
} priority_queue<node>que;
bool Astar(node now)
{
ms(vis,);
while(!que.empty()) que.pop(); now.status = cantor(now.s);
now.g = ;
now.h = dis_h(now.s);
now.f = now.f + now.h;
pre[now.status] = -; //开始状态的上一个状态为-1,用于输出路径时“刹车”
vis[now.status] = ;
que.push(now); node tmp;
while(!que.empty())
{
now = que.top();
que.pop();
if(now.status==AIM) //找到了123456789的状态
return true; int x = now.loc/;
int y = now.loc%;
for(int i = ; i<; i++)
{
int xx = x + dir[i][];
int yy = y + dir[i][];
if(xx>= && xx<= && yy>= && yy<=)
{
tmp = now;
tmp.s[x*+y] = tmp.s[xx*+yy]; //交换位置,下同
tmp.s[xx*+yy] = ;
tmp.status = cantor(tmp.s);
if(!vis[tmp.status])
{
vis[tmp.status] = ;
tmp.loc = xx*+yy;
tmp.g++; //g
tmp.h = dis_h(tmp.s); //h
tmp.f = tmp.g + tmp.h; //f
pre[tmp.status] = now.status; //tmp.status的上一个状态为now.status
path[tmp.status] = op[i]; //保存操作
que.push(tmp);
}
}
}
}
return ;
} void Print(int status)
{
if(pre[status]==-) return;
Print(pre[status]); //追溯上一个状态
putchar(path[status]);
} int main()
{
char str[];
while(gets(str))
{
node now;
int cnt = ;
for(int i = ; str[i]; i++)
{
if(str[i]==' ') continue;
if(str[i]=='x') now.s[cnt] = , now.loc = cnt++;
else now.s[cnt++] = str[i]-'';
}
if(!Astar(now))
puts("unsolvable");
else
Print(AIM), putchar('\n');
}
}

POJ1077 Eight —— A*算法的更多相关文章

  1. POJ1077 Eight —— IDA*算法

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

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

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

  3. HDU3567 Eight II —— IDA*算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others)  ...

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

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

  5. B树——算法导论(25)

    B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...

  6. 分布式系列文章——Paxos算法原理与推导

    Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上有很多讲解Paxos算法的文章,但是质量参差不齐.看了很多关于Paxos的资 ...

  7. 【Machine Learning】KNN算法虹膜图片识别

    K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  8. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  9. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

随机推荐

  1. D3拖动效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. spring boot -- 无法读取html文件,碰到的坑

    碰到的坑,无法Controller读取html文件 1. Controller类一定要使用@Controller注解,不要用@RestController 2. resource目录下创建templa ...

  3. vue之监听事件

    一.v-on 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码. 简写形式  用@代替 v-on: <button v-on:click="co ...

  4. 精通python网络爬虫之自动爬取网页的爬虫 代码记录

    items的编写 # -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentati ...

  5. CentOS 5.4 final下Systemtap的安装

    CentOS 5.4 final下Systemtap的安装  时间:2015-02-11来源:linux网站 作者:zklth  一.Systemtap运行环境需求   (1)linux kernel ...

  6. 超级强大的淘宝开源平台(taobao-code)

    今天发现了一个免费又高级的开源SVN服务器,taobao,阿里云CODE.迫不及待的注册了一个.感觉不错,分享给大家. 先说说我们用过的几个SVN服务器吧: google code oksvn(感觉不 ...

  7. IOS -- base64编码

    在iOS7以后可以用NSData自带的base64EncodedStringWithOptions进行编解码: 方法如下: - (NSString *)encodeToBase64String:(UI ...

  8. oracle学习 第二章 限制性查询和数据的排序 ——03

    这里.我们接着上一小节2.6留下的问题:假设要查询的字符串中含有"_"或"%".又该如何处理呢? 開始今天的学习. 2.7  怎样使用转义(escape)操作符 ...

  9. [转] 一句shell命令搞定代码行数统计

    今天面试时,突然被面试官问到怎样用shell命令搞定某个文件夹下java代码行数的统计. 想了一下,基本思路就是找到这个文件夹下面的所有java文件,然后每个文件统计一下代码,外层套个for循环,叠加 ...

  10. [转]Linux上程序执行的入口--Main

    main()函数,想必大家都不陌生了,从刚开始写程序的时候,大家便开始写main(),我们都知道main是程序的入口.那main作为一个函数,又是谁调用的它,它是怎么被调用的,返回给谁,返回的又是什么 ...