Eight

Descriptions:

简单介绍一下八数码问题:
在一个3×3的九宫格上,填有1~8八个数字,空余一个位置,例如下图:

1 2 3
4 5 6
7 8  

在上图中,由于右下角位置是空的,你可以移动数字,比如可以将数字6下移一位:

1 2 3   1 2 3
4 5 6 4 5  
7 8     7 8 6

或者将数字8右移一位:

1 2 3   1 2 3
4 5 6 4 5 6
7 8     7   8

1~8按顺序排列的情况称为“初始状态”(如最上方图)。“八数码问题”即是求解对于任意的布局,将其移动至“初始状态”的方法。 
给定一个现有的九宫格布局,请输出将它移动至初始状态的移动方法的步骤。
Input

输入包含多组数据,处理至文件结束。每组数据占一行,包含8个数字和表示空位的‘x’,各项以空格分隔,表示给定的九宫格布局。 
例如,对于九宫格

1 2 3
  4 6
7 5 8

输入应为:1 2 3 x 4 6 7 5 8

Output

对于每组输入数据,输出一行,即移动的步骤。向上、下、左、右移动分别用字母u、d、l、r表示;如果给定的布局无法移动至“初始 状态”,请输出unsolvable。
如果有效的移动步骤有多种,输出任意即可。

Sample Input

  1. 2 3 4 1 5 x 7 6 8

Sample Output

  1. ullddrurdllurdruldr

题目链接

https://vjudge.net/problem/HDU-1043

其实就是反向bfs,不过用了一个新的方法去存放拼图序列,康托展开即把拼图(x12345678)全排列,再用数字去表示,简而言之就是用不同的数字去代替拼图序列,使之跟简单、快速的搜索

不会康托展开不关系,点击下面链接,现学现会

https://www.cnblogs.com/sky-stars/p/11216035.html

AC代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <fstream>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <deque>
  7. #include <vector>
  8. #include <queue>
  9. #include <string>
  10. #include <cstring>
  11. #include <map>
  12. #include <stack>
  13. #include <set>
  14. #include <sstream>
  15. #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
  16. #define Mod 1000000007
  17. #define eps 1e-6
  18. #define ll long long
  19. #define INF 0x3f3f3f3f
  20. #define MEM(x,y) memset(x,y,sizeof(x))
  21. #define Maxn 362880+5//876543210的hash值为362880 即最多出现362880种可能
  22. using namespace std;
  23. static const int FAC[] = {, , , , , , , , , }; // 阶乘
  24. struct node
  25. {
  26. string path;//路径
  27. int hashs;//hash值
  28. int pos;//0的位置
  29. };
  30. node now,net;
  31. queue<node>q;
  32. int dt[][]= {{,},{-,},{,},{,-}};//四个方向
  33. char op[]="udlr";//这个与上面的搜索方向是反的,因为是反向bfs
  34. int tmp[];//临时存储拼图的序列
  35. int result=;//123456780 最终答案的hash值
  36. string path[Maxn];//path[x] hash值为x的路径
  37. int vis[Maxn];//vis[x] hash值为x的拼图序列是否标记过
  38. //康托展开
  39. int cantor(int *a)
  40. {
  41. int x = ;
  42. for (int i = ; i < ; ++i)
  43. {
  44. int smaller = ; // 在当前位之后小于其的个数
  45. for (int j = i + ; j < ; ++j)
  46. {
  47. if (a[j] < a[i])
  48. smaller++;
  49. }
  50. x += FAC[ - i - ] * smaller; // 康托展开累加
  51. }
  52. return x+; // 康托展开值
  53. }
  54. //逆康托展开
  55. void decantor(int x, int *a)
  56. {
  57. vector<int> v; // 存放当前可选数
  58. for(int i=; i<; i++)
  59. v.push_back(i);
  60. for(int i=; i<; i++)
  61. {
  62. int r = x % FAC[-i-];
  63. int t = x / FAC[-i-];
  64. x = r;
  65. sort(v.begin(),v.end());// 从小到大排序
  66. a[i]=v[t]; // 剩余数里第t+1个数为当前位
  67. v.erase(v.begin()+t); // 移除选做当前位的数
  68. }
  69. }
  70. void bfs()
  71. {
  72. MEM(vis,);//初始化
  73. for(int i=; i<; i++)//tmp一开始为123456780,从这开始打散拼图
  74. tmp[i]=i+;
  75. tmp[]=;
  76. now.pos=;
  77. now.hashs=result;
  78. now.path="";
  79. path[result]="";
  80. vis[result]=;
  81. q.push(now);
  82. while(!q.empty())
  83. {
  84. now=q.front();
  85. q.pop();
  86. for(int i=; i<; i++)//四个方向
  87. {
  88. int tx=now.pos/+dt[i][];
  89. int ty=now.pos%+dt[i][];
  90. if(tx>=&&ty>=&&tx<=&&ty<=)//没走出去拼图
  91. {
  92. net=now;
  93. net.pos=tx*+ty;
  94. decantor(now.hashs-,tmp);//求tmp
  95. swap(tmp[now.pos],tmp[net.pos]);//得到新的tmp
  96. net.hashs=cantor(tmp);//得到新tmp对应的hash
  97. if(!vis[net.hashs])//这都bfs老套路了 没啥说的
  98. {
  99. vis[net.hashs]=;
  100. net.path=op[i]+net.path;
  101. q.push(net);
  102. path[net.hashs]=net.path;
  103. }
  104. }
  105. }
  106. }
  107. return;
  108. }
  109. int main()
  110. {
  111. bfs();
  112. char x;
  113. while(cin>>x)//输入格式 没啥说的
  114. {
  115. if(x=='x')
  116. {
  117. now.pos=;
  118. tmp[]=;
  119. }
  120. else
  121. {
  122. tmp[]=x-'';
  123. }
  124. for(int i=; i<; i++)
  125. {
  126. cin>>x;
  127. if(x=='x')
  128. {
  129. now.pos=i;
  130. tmp[i]=;
  131. }
  132. else
  133. {
  134. tmp[i]=x-'';
  135. }
  136. }
  137. now.hashs=cantor(tmp);//求出tmp这个拼图序列的hash值
  138. if(!vis[now.hashs])//这个hash没标记过,即没产生过这个拼图序列
  139. cout<<"unsolvable"<<endl;
  140. else
  141. cout<<path[now.hashs]<<endl;//输出hash的路径
  142. }
  143. return ;
  144. }

【HDU - 1043】Eight(反向bfs+康托展开)的更多相关文章

  1. HDU 1043 Eight(反向BFS+打表+康托展开)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目大意:传统八数码问题 解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各 ...

  2. hdu.1430.魔板(bfs + 康托展开)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  3. HDU 1043 Eight (A* + HASH + 康托展开)

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  4. HDU_1043 Eight 【逆向BFS + 康托展开 】【A* + 康托展开 】

    一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=1043 二.两种方法 该题很明显,是一个八数码的问题,就是9宫格,里面有一个空格,外加1~8的数字,任意 ...

  5. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  6. POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3

    http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...

  7. HDU 1430 魔板(康托展开+BFS+预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  8. HDU - 1430 魔板 【BFS + 康托展开 + 哈希】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路 我刚开始 想到的 就是 康托展开 但是这个题目是 多组输入 即使用 康托展开 也是会T的 ...

  9. hdu 1430 (BFS 康托展开 或 map )

    第一眼看到这题就直接BFS爆搜,第一发爆了内存,傻逼了忘标记了,然后就改,咋标记呢. 然后想到用map函数,就8!个不同的排列,换成字符串用map标记.然后又交一发果断超时,伤心,最恨超时,还不如来个 ...

随机推荐

  1. C#管理服务停止启动

    由于机器性能问题,把许多服务关闭了,需要用的时候再开启,这样每次都打开服务管理或cmd命令比较麻烦.就自己写了工具显示在桌面上; 声明:ServiceController myController = ...

  2. WinForm子线程调用主线程

    public Form1() { InitializeComponent(); Thread t = new Thread(ThreadWorker); t.Start(); } private vo ...

  3. AndroidStudio问题汇总

    1.Error:Execution failed for task ':app:preDebugAndroidTestBuild'.> Conflict with dependency 'com ...

  4. 关于C中可变长参数

    前言 可变长参数指函数的参数个数在调用时才能确定的函数参数.基本上各种语言都支持可变长参数,在特定情形下,可变长参数使用起来非常方便.c语言中函数可变长参数使用“...”来表示,同时可变长参数只能位于 ...

  5. Delphi与Windows 7下的用户账户控制(UAC)机制(有可能需要取消enable runtime themes)

    WIN7/WIN8/WIN10, Vista提供的UAC机制,它的主要目的是防止对于操作系统本身的恶意修改.对于Delphi程序的影响,UAC主要在于以下几点:1.由于UAC机制,Delphi对于系统 ...

  6. CentOS7下group和group-、passwd与passwd-之间的区别

    今天查看/etc/group时,意外发现另外一个/etc/group-,查看了一下2个文件,发现大部分内容是一致的.这就有点搞不懂了,后面这个group是有啥用呢呢?diff对比了一下,相比group ...

  7. QML动画概述(几十篇相关博客)

    QML提供了丰富的动画元素,说起动画,无非是给UI增光添彩罢了.在QML中,动画常常与State和Transition联系在一起,这几个概念(下面的例子中都用到了)都比较简单,相关介绍可查看Qt官方文 ...

  8. XML转义字符 如"&"

    解析数据 XML 解析器通常情况下会处理XML文档中的所有文本. 当XML元素被解析的时候,XML元素内部的文本也会被解析,例如: <message>Hello Word!</mes ...

  9. 微信小程序ES6方法Promise封装接口

    为何要封装接口? 有小程序开发的经验者,相信对微信API Request很熟悉了.对接接口时,有大部分的开发者都是直接调用request方法,去请求后台接口并渲染数据.诚然,直接使用api发起请求对接 ...

  10. Mac iTerm2使用lrzsz上传和下载文件

    Mac iTerm2使用lrzsz对服务器上传和下载文件 安装工具 首先需要安装iTerm2和homebrew,在终端中执行(打开终端,使用搜索(command + space),输入terminal ...