经典的八数码问题,用来练习各种搜索=_=。这题我用的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] = {0}, fa[M] = {0}, move[M] = {0};
sss begin, end;
int step[4][2] = {{-1,0},{0,-1},{0,1},{1,0}};
int color[M] = {0};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 = 0;for (int i = 1; i <= 3; ++i)for (int j = 1; j <= 3; ++j){int x = (i-1)*3+j;z += abs(i-(a.state[x]-1)/3) + abs(j-(a.state[x]-(a.state[x]-1)/3*3));}return z;
}int jiecheng[N] = {0,1,2,6,24,120,720,5040,40320,362880};
int make_num(sss a) // 康拓展开
{int ans = 0; bool xiao[N] = {0};for (int i = 1; i <= 9; ++i){int count = 0; xiao[a.state[i]] = 1;for (int j = 1; j < a.state[i]; ++j)if (!xiao[j]) count++;ans += count * jiecheng[N-i-1];}return ans;
}bool in(sss now, int mo) // 移动可行
{int x = (now.place-1)/3+1, y = now.place-(x-1)*3;x += step[mo-1][0]; y += step[mo-1][1];if (x < 1 || x > 3 || y < 1 || y > 3) 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 = -3; i <= 3; i+=2){if (!in(u,(i+5)/2)) 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] == 1){if (g[u.num] + 1 < g[v.num]){f[v.num] = f[v.num] - g[v.num] + g[u.num] + 1;g[v.num] = g[u.num] + 1; move[v.num] = i;q.push(v); fa[v.num] = u.num;}}else if (color[v.num] == 2){if (g[u.num] + 1 < g[v.num]){f[v.num] = f[v.num] - g[v.num] + g[u.num] + 1;g[v.num] = g[u.num] + 1; fa[v.num] = u.num;q.push(v); color[v.num] = 1; move[v.num] = i;}}else{g[v.num] = g[u.num] + 1;f[v.num] = h(v) + g[v.num];color[v.num] = 1; fa[v.num] = u.num;q.push(v); move[v.num] = i;}}color[u.num] = 2;}
}char change(int x)
{if (x == -1) return 'l';else if (x == -3) return 'u';else if (x == 1) return 'r';else return 'd';
}void print() // 输出
{char s[M], snum = 0;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 > 0; --i)printf("%c", s[i]);printf("\n");
}int main()
{char s[2];for (int i = 1; i <= 9; ++i){scanf("%s", s);if (s[0] != 'x') begin.state[i] = s[0] - '0';else{begin.state[i] = 9;begin.place = i;}end.state[i] = i;}begin.num = make_num(begin);end.num = make_num(end);A_star();print();
}

转载于:https://www.cnblogs.com/handsomeJian/p/3947818.html

poj 1077 Eight(A*)相关推荐

  1. POJ - 1077 Eight(A∗算法)

    POJ - 1077 Eight(A∗算法) #include<iostream> #include<algorithm> #include<map> #inclu ...

  2. POJ 3414 Pots(罐子)

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

  3. POJ 2287 田忌赛马(贪心)

    文章目录 1. 题目 1.1 题目链接 1.2 题目大意 1.3 解题思路 2. Accepted 代码 1. 题目 1.1 题目链接 http://poj.org/problem?id=2287 1 ...

  4. poj题目分类(转)--方便分类做题

    POJ推荐50题以及ACM训练方案(转) POJ 推荐50题 第一类 动态规划(至少6题,2479 和 2593 必做) 2479 和 2593 1015 1042(可贪心)  1141 1050 1 ...

  5. POJ 1088----滑雪(DP)

    原题连接:http://poj.org/problem?id=1088 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当 ...

  6. poj 1088 滑雪 (dp)

    题目链接 题意就不多解释了,题目思路很简单,搜索就行了,但是暴搜会TLE,但是对于每一个dfs(X, Y),如果参数一样的话结果也是一样的,我们用一个二维数组去保存每次计算的位置的结果,最后从所有的解 ...

  7. poj 3255 Roadblocks (SPFA)

    题目大意:在一个图上有许多个农场,有个人从1农场出发,到他的朋友n农场去,他不想走一条最短路径,这次他想换条路走,要你帮他找一条次短路径,次短路的定义是,比最短路径长度短(可能有多条),但是不会比其他 ...

  8. POJ - 1847 Tram(dijkstra)

    题意:有向图有N个点,当电车进入交叉口(某点)时,它只能在开关指向的方向离开. 如果驾驶员想要采取其他方式,他/她必须手动更换开关.当驾驶员从路口A驶向路口B时,他/她尝试选择将他/她不得不手动更换开 ...

  9. POJ 3253-Fence Repair(堆)

    Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27055   Accepted: 8800 Des ...

最新文章

  1. ACM——模拟(hard) 刷题总结
  2. c#之旅--第六天(类,对象,方法)
  3. SQL Server 2000 Service Pack 4 中所修复的 bug 的列表
  4. stringstream精度问题
  5. H5活动刮刮卡功能的实现与注意事项
  6. 代码规范之eslint+prettier实践
  7. arcgis-shp文件属性表导出为dbf或txt
  8. 获取系统进程信息和进程依赖的dll信息--CreateToolhelp32Snapshot
  9. 【题解】 Codeforces Edu41 F. k-substrings (字符串Hash)
  10. 北京内推 | ​美团无人车团队招聘视觉算法实习生
  11. springmvc如何使用视图解析器_SpringMVC工作原理
  12. C++单元测试框架的比较(zz)
  13. 【转载】WinCE中的RAM-Based Registry与HIVE-Based Registry
  14. FCN数据预处理(code)
  15. python+flask搭建CNN在线识别手写中文网站
  16. edi python_在不从edi运行的情况下调用python函数
  17. linux支持ext2格式吗,linux正统标准文件系统ext2详解
  18. 泛微OA中怎么导入html模板,如何在OA系统中设置模板标题
  19. DAP -Link 仿真下载 STM32 教程
  20. 用友T+、U8、NC系列,致远OA产品二次开发

热门文章

  1. 【Linux】一步一步学Linux——batch命令(134)
  2. git pull冲突解决
  3. CF-525E(E. Anya and Cubes) Meet-in-the-Middle
  4. LeTax报错之 Incomplete \iffalse
  5. 问题:python3关于json文件多余一行后发生的错误
  6. taylor+swift纽约公寓_豪宅控!Taylor Swift究竟有多喜欢买豪宅!
  7. c++中lambda表达式用法
  8. 关于FragmentPager实现Fragment的滑动切换
  9. linux移植wifi sd8688.bin 最新固件,[ZZ]浅析firmware完整生存和使用流程
  10. Excel 打开csv显示在一个单元格