1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <queue>
  7. #include <set>
  8. using namespace std;
  9. /*
  10. 2 6 4 1 3 7 0 5 8
  11. 8 1 5 7 3 6 4 0 2
  12. 1 2 3 4 5 0 7 8 6
  13. 1 2 3 4 5 6 7 8 0
  14. */
  15. typedef int State[];
  16. const int maxstate = ;
  17. State st[maxstate], goal; //状态数组, 所有状态都保存在这里
  18. int dist[maxstate]; //距离数组
  19. set<int> vis; //编码
  20. //如果需要打印方案,可以在这里加一个"父亲编号" 数组 int fa[maxstate]
  21. int fa[maxstate];
  22. void init_lookup_table();
  23. int try_to_insert(int s);
  24. int BFS();
  25. void solve();
  26. const int dx[] = {-, , , };
  27. const int dy[] = {, , -, };
  28. void print(State s, int front)
  29. {
  30. for (int i = ; i < ; i++) {
  31. if (i % == ) cout << endl;
  32. cout << st[front][i] << " ";
  33. }
  34. cout << endl;
  35. }
  36. bool judge(int x, int y)
  37. {
  38. return (x >= && x < ) && (y >= && y < );
  39. }
  40. void init_lookup_table()
  41. {
  42. for (int i = ; i < ; i++) {
  43. scanf("%d", &st[][i]); //起始状态
  44. }
  45. for (int i = ; i < ; i++) {
  46. scanf("%d", &goal[i]);
  47. }
  48. vis.clear();
  49. }
  50. int try_to_insert(int s)
  51. {
  52. int code = ; //把st[s]映射到code
  53. for (int i = ; i < ; i++) {
  54. code = code * + st[s][i];
  55. }
  56. if (vis.count(code)) return ;
  57. vis.insert(code);
  58. return ; //HashCode
  59. }
  60. //BFS, 返回目标状态在st数组下标
  61. int BFS()
  62. {
  63. init_lookup_table(); //初始化查找表
  64. int front = , rear = ; //不使用下标0, 因为0被看作不存在
  65. while (front < rear) {
  66. State& s = st[front]; //用引用简化代码
  67. if (memcmp(goal, s, sizeof(s)) == ) {
  68. return front; //找到目标状态, 成功返回
  69. }
  70. int z;
  71. for (z = ; z < ; z++) {
  72. if (!s[z]) break; //找“0”的位置
  73. }
  74. int x = z / , y = z % ; //模拟 行, 列
  75. for (int d = ; d < ; d++) { //四个方向
  76. int newx = x + dx[d];
  77. int newy = y + dy[d];
  78. int newz = newx * + newy; //模拟到一维数组的地方 , 空格将要移动到的地方
  79. if (judge(newx, newy)) { //移动合法
  80. State &t = st[rear]; //得到队尾元素
  81. memcpy(&t, &s, sizeof(s)); // 将将 s 添加到队尾
  82. //数字 和 空格交换位置
  83. t[newz] = s[z]; //z位置为 空格
  84. t[z] = s[newz];
  85. dist[rear] = dist[front] + ; //更新新结点的距离值
  86. if (try_to_insert(rear)) rear++; //如果成功插入查找表, 修改队尾指针
  87. }
  88. }
  89. front++; //拓展完毕, 修改队首指针
  90. //打印
  91. print(st[front], front);
  92. }
  93. return ; //失败
  94. }
  95. void solve()
  96. {
  97. int ans = BFS();
  98. if (ans > ) printf("%d\n", dist[ans]);
  99. else printf("-1\n");
  100. }
  101. int main()
  102. {
  103. solve();
  104. return ;
  105. }

BFS:八数码问题的更多相关文章

  1. BFS(八数码) POJ 1077 || HDOJ 1043 Eight

    题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...

  2. UVALive 6665 Dragon’s Cruller --BFS,类八数码问题

    题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...

  3. [cdoj1380] Xiper的奇妙历险(3) (八数码问题 bfs + 预处理)

    快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚 ...

  4. 八数码问题+路径寻找问题+bfs(隐式图的判重操作)

    Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 p ...

  5. HDU 1043 Eight (BFS&#183;八数码&#183;康托展开)

    题意  输出八数码问题从给定状态到12345678x的路径 用康托展开将排列相应为整数  即这个排列在全部排列中的字典序  然后就是基础的BFS了 #include <bits/stdc++.h ...

  6. 【算法】BFS+哈希解决八数码问题

    15拼图已经有超过100年; 即使你不叫这个名字知道的话,你已经看到了.它被构造成具有15滑动砖,每一个从1到15上,并且所有包装成4乘4帧与一个瓦块丢失.让我们把丢失的瓷砖“X”; 拼图的目的是安排 ...

  7. hdu-1043(八数码+bfs打表+康托展开)

    参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...

  8. Poj 1077 eight(BFS+全序列Hash解八数码问题)

    一.题意 经典的八数码问题,有人说不做此题人生不完整,哈哈.给出一个含数字1~8和字母x的3 * 3矩阵,如: 1  2  X            3 4  6            7  5  8 ...

  9. HDU1043 八数码(BFS + 打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...

  10. 习题:八数码难题(双向BFS)

    八数码难题(wikioi1225) [题目描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出 ...

随机推荐

  1. HDU 2262 Where is the canteen 期望dp+高斯消元

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2262 Where is the canteen Time Limit: 10000/5000 MS ...

  2. golang type

    参考链接 https://blog.csdn.net/tzs919/article/details/53571632 type是golang中非常重要的关键字,常见的就是定义结构体,但是其功能远不止是 ...

  3. 第六周PSP&进度条

    团队项目PSP 一.表格:     C类型 C内容 S开始时间 E结束时间 I时间间隔 T净时间(mins) 预计花费时间(mins) 讨论 讨论alpha完成情况并总结 9:40 11:20 17 ...

  4. java poi给sheet表格中的某个单元格添加批注

    Label l = , , "A cell with a comment"); WritableCellFeatures cellFeatures = new WritableCe ...

  5. Windows 常见错误总结

    本篇主要记录Windows 系统使用中存在的问题和解决方案,会保持持续更新...(若你们遇到的问题或有更好的解决方法,还望在评论区留言,谢谢) 1.win10 unable to save C:\wi ...

  6. 每个Android开发者必须知道的内存管理知识

    原文:每个Android开发者必须知道的内存管理知识 拷贝在此处,以备后续查看. 相信一步步走过来的Android从业者,每个人都会遇到OOM的情况.如何避免和防范OOM的出现,对于每一个程序员来说确 ...

  7. js 时间处理函数 获取今天的前几天和后几天的任意一天

      var now = new Date(); let today = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDa ...

  8. .NET Core 中的并发编程

    今天我们购买的每台电脑都有一个多核心的 CPU,允许它并行执行多个指令.操作系统通过将进程调度到不同的内核来发挥这个结构的优点. 然而,还可以通过异步 I/O 操作和并行处理来帮助我们提高单个应用程序 ...

  9. 对synchronized的一点理解

    一.synchronized的使用(一).synchronized同步方法1. “非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全”问题.2. 如果多个线程共同访问 ...

  10. enginefuncs_t 结构体中的函数

    就是常见的 g_engfuncs 中的函数.AMXX 里就是 fakemeta 的 EngFunc_** // 这些函数由引擎提供给EXTDLL使用.mp.dll hl.dll ... typedef ...