经典的八数码问题,用来练习各种搜索=_=。这题我用的A*做的,A*的主要思想就是在广搜的时候加了一个估价函数,用来评估此状态距离最终状态的大概距离。这样就可以省下很多状态不用搜索。对于每个状态设置一个函数 h(x),这就是估价函数了(可能名词不太对请见谅),再设置一个函数 g(x), 这存的是初始状态到当前状态所用步数(或距离,视估价函数而定),再设函数 f(x) = g(x) + h(x),我们对每个状态的 f(x)的值进行排序, 然后从当前 f(x) 最小的状态继续搜索,直到搜索到最终状态或者没有后继状态。

上代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#define N 10
#define M 500000
using namespace std; struct sss
{
int state[N];
int num, place;
};
priority_queue<sss> q; int f[M], g[M] = {}, fa[M] = {}, move[M] = {};
sss begin, end;
int step[][] = {{-,},{,-},{,},{,}};
int color[M] = {}; bool operator < (sss a, sss b) { return f[a.num] > f[b.num]; }
bool operator == (sss a, sss b) { return a.num == b.num; } int h(sss a) // h(v)
{
int z = ;
for (int i = ; i <= ; ++i)
for (int j = ; j <= ; ++j)
{
int x = (i-)*+j;
z += abs(i-(a.state[x]-)/) + abs(j-(a.state[x]-(a.state[x]-)/*));
}
return z;
} int jiecheng[N] = {,,,,,,,,,};
int make_num(sss a) // 康拓展开
{
int ans = ; bool xiao[N] = {};
for (int i = ; i <= ; ++i)
{
int count = ; xiao[a.state[i]] = ;
for (int j = ; j < a.state[i]; ++j)
if (!xiao[j]) count++;
ans += count * jiecheng[N-i-];
}
return ans;
} bool in(sss now, int mo) // 移动可行
{
int x = (now.place-)/+, y = now.place-(x-)*;
x += step[mo-][]; y += step[mo-][];
if (x < || x > || y < || y > ) return false;
else return true;
} void A_star() // A*
{
q.push(begin); f[begin.num] = h(begin);
while (!q.empty())
{
sss u = q.top(); q.pop();
if (u == end)
return;
for (int i = -; i <= ; i+=)
{
if (!in(u,(i+)/)) continue;
sss v; v = u; swap(v.state[u.place+i], v.state[u.place]);
v.place = u.place + i; v.num = make_num(v);
if (color[v.num] == )
{
if (g[u.num] + < g[v.num])
{
f[v.num] = f[v.num] - g[v.num] + g[u.num] + ;
g[v.num] = g[u.num] + ; move[v.num] = i;
q.push(v); fa[v.num] = u.num;
}
}
else if (color[v.num] == )
{
if (g[u.num] + < g[v.num])
{
f[v.num] = f[v.num] - g[v.num] + g[u.num] + ;
g[v.num] = g[u.num] + ; fa[v.num] = u.num;
q.push(v); color[v.num] = ; move[v.num] = i;
}
}
else
{
g[v.num] = g[u.num] + ;
f[v.num] = h(v) + g[v.num];
color[v.num] = ; fa[v.num] = u.num;
q.push(v); move[v.num] = i;
}
}
color[u.num] = ;
}
} char change(int x)
{
if (x == -) return 'l';
else if (x == -) return 'u';
else if (x == ) return 'r';
else return 'd';
} void print() // 输出
{
char s[M], snum = ;
int k = fa[end.num];
s[++snum] = change(move[end.num]);
while (k != begin.num)
{
s[++snum] = change(move[k]);
k = fa[k];
}
for (int i = snum; i > ; --i)
printf("%c", s[i]);
printf("\n");
} int main()
{
char s[];
for (int i = ; i <= ; ++i)
{
scanf("%s", s);
if (s[] != 'x') begin.state[i] = s[] - '';
else
{
begin.state[i] = ;
begin.place = i;
}
end.state[i] = i;
}
begin.num = make_num(begin);
end.num = make_num(end);
A_star();
print();
}

poj 1077 Eight(A*)的更多相关文章

  1. POJ 2431 Expedition(探险)

    POJ 2431 Expedition(探险) Time Limit: 1000MS   Memory Limit: 65536K [Description] [题目描述] A group of co ...

  2. POJ 3414 Pots(罐子)

    POJ 3414 Pots(罐子) Time Limit: 1000MS    Memory Limit: 65536K Description - 题目描述 You are given two po ...

  3. POJ 3281 Dining (网络流)

    POJ 3281 Dining (网络流) Description Cows are such finicky eaters. Each cow has a preference for certai ...

  4. POJ 1847 Tram (最短路径)

    POJ 1847 Tram (最短路径) Description Tram network in Zagreb consists of a number of intersections and ra ...

  5. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  6. HDU 1043 & POJ 1077 Eight(康托展开+BFS | IDA*)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  7. POJ 1077 Eight (BFS+康托展开)详解

    本题知识点和基本代码来自<算法竞赛 入门到进阶>(作者:罗勇军 郭卫斌) 如有问题欢迎巨巨们提出 题意:八数码问题是在一个3*3的棋盘上放置编号为1~8的方块,其中有一块为控制,与空格相邻 ...

  8. POJ 题目分类(转载)

    Log 2016-3-21 网上找的POJ分类,来源已经不清楚了.百度能百度到一大把.贴一份在博客上,鞭策自己刷题,不能偷懒!! 初期: 一.基本算法: (1)枚举. (poj1753,poj2965 ...

  9. POJ题目分类(转)

    初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推. ...

随机推荐

  1. swift3.0 中NSNotification 的使用

    swift3.0 有很大变化,其中之一就是NSNotification使用跟原来不一样,以前NSNotification name是String:3.0中定义了一个类型NSNotification.n ...

  2. Android 滑动效果基础篇(三)—— Gallery仿图像集浏览

    Android系统自带一个Gallery浏览图片的应用,通过手指拖动时能够非常流畅的显示图片,用户交互和体验都很好. 本示例就是通过Gallery和自定义的View,模仿实现一个仿Gallery图像集 ...

  3. mysql的两阶段提交协议

    http://www.cnblogs.com/hustcat/p/3577584.html   前两天和百度的一个同学聊MySQL两阶段提交,当时自信满满的说了一堆,后来发现还是有些问题的理解还是比较 ...

  4. 细看InnoDB数据落盘 图解 MYSQL 专家hatemysql

    http://hatemysql.com/?p=503 1.  概述 前面很多大侠都分享过MySQL的InnoDB存储引擎将数据刷新的各种情况.我们这篇文章从InnoDB往下,看看数据从InnoDB的 ...

  5. Word2010 清除样式

    使用场景         有时候我们在网页上面粘贴一些精华文章或者从去整理别人已经完成的word的时候,会发现它自带的格式,可能并不是我们所理想的格式,所以此时就不得不去重新编辑其格式,但是word里 ...

  6. 关于File.getPath,File.getAbsolutePath,File.getCanonicalPath的区别

    这个问题, 不了解一下还是挺恍惚它们之间的区别的. 其实也挺简单的. getPath()-->>new File()时的路径 getAbsolutePath()-->>当前路径 ...

  7. iframe自适应高度的多种方法方法小结

    对于自适应高度的代码有很多,可效率什么的考虑进来好代码就不多见了,不过思路倒是差不多的  不带边框的iframe因为能和网页无缝的结合从而不刷新页面的情况下更新页面的部分数据成为可能,可是 ifram ...

  8. Linux(Debian) vps安装gnome桌面+VNC

      昨天转载了一篇关于在Linux VPS上安装xface桌面并VNC连接的文章,因为文章是基于CentOS系统来操作的,有热心读者希望有一个Debian下的类似的东西,这就促成了今天的这篇文字.需要 ...

  9. 浅谈C/C++中的static和extern关键字 转

    原文:http://developer.51cto.com/art/201104/256820.htm static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.extern, &quo ...

  10. 小白日记28:kali渗透测试之Web渗透-扫描工具-Nikto

    扫描工具-Nikto #WEB渗透 靶机:metasploitable 靶场:DVWA[默认账号/密码:admin/password] #新手先将DVWA的安全性,调到最低,可容易发现漏洞 侦察[减少 ...