经典的八数码问题,用来练习各种搜索=_=。这题我用的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. SQL中declare申明变量

    在sql语句中加入�变量. declare @local_variable data_type 声明时须要指定变量的类型, 能够使用set和select对变量进行赋值, 在sql语句中就能够使用@lo ...

  2. javaio学习笔记-字符流类(1)

    1.java.io包中的字符流类-BufferedReader和BufferedWriter: BufferedReader:缓存的输入字符流; BufferedWriter:缓存的输出字符流; In ...

  3. sql操作事务SqlTransHelper类实现

    具体实现代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; usin ...

  4. HOW MYSQL USES INTERNAL TEMPORARY TABLES

    HOW MYSQL USES INTERNAL TEMPORARY TABLES Table of Contents [hide] 1)UNION queries 2)Some views 3)SQL ...

  5. Ruby on Rails Tutorial 第三章 静态页面

    1.生成静态页面 $ rails generate controller StaticPages home help    #生成主页和帮助页面的路由.控制器及静态页面 $ rails destroy ...

  6. Python学习 之 编程

    1.搭建python环境 交互模式:输入python进入交互模式,exit()退出交互模式 文本模式:新建*.py文件,编辑*.py文件,运行python *.py 2.python文件类型 (1)源 ...

  7. sizeWithFont 不是线程安全。

    在ios开发中经常使用用sizeWithFont 方法来计算UILabel 的frame, 例如动态计算UITableViewCell 的高度,在主线程处理没有问题,但是在子线程用此方法来计算就会出现 ...

  8. MySQL查询优化--细节理论

    select的 high_priority还是比较有用,在实践中,平均5~6秒提高到3秒 ======================================================= ...

  9. hdu1051 Wooden Sticks

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1051 大意:求最少升序序列的个数. #include <cstdio> #include &l ...

  10. 琐碎-到底要不要SSH免密码设置

    搭建了很多次hadoop2.2.0了,尝试过很多不同的启动方法.配置参数.位置,其中涉及到到底要不要配置SSH免密码登录的问题 先是搞清楚为什么需要SSH免密码登录 SSH免密码登录操作步骤: ... ...