题意:经典八数码问题

思路:双向bfs

ps:还有a*算法(还不会)等解法。

代码:

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<queue>
  5. using namespace std;
  6.  
  7. #define MAXN 362885//最多组合个数:9!=362880
  8.  
  9. int dir[]={-,,-,};//4个方向移动:u,d,l,r
  10. char opF[]={'u','d','l','r'};//正向bfs操作
  11. char opR[]={'d','u','r','l'};//反向bfs操作
  12. int fac[]={,,,,,,,,};//阶乘
  13. bool visF[MAXN];//正向访问标志
  14. bool visR[MAXN];//
  15. string sTarg="";//目标棋盘
  16.  
  17. struct node{//存储棋盘信息
  18. string s;//当前棋盘
  19. int xLoca;//x位置
  20. }t;
  21.  
  22. struct node2{//存储操作
  23. int idF,idR;//正向前驱、反向前驱
  24. char cF,cR;//操作
  25. }op[MAXN];
  26.  
  27. int cantor_hash(string s){//康托展开,一共n位
  28. int n=;//共9位
  29. int i,j,temp,num;
  30. num=;
  31. for(i=;i<n-;i++){//n为位数
  32. temp=;
  33. for(j=i+;j<n;j++){
  34. if(s[j]<s[i])temp++;
  35. }
  36. num+=fac[n-(i+)]*temp;
  37. }
  38. return num;//从0开始
  39. }
  40.  
  41. void display(int i){//输出正向操作
  42. if(op[i].idF==-)return;
  43. display(op[i].idF);
  44. printf("%c",op[i].cF);
  45. }
  46.  
  47. void dBfs(){
  48. queue<node>qF,qR;//正向队列,反向队列
  49. node tmp1,tmp2;//棋盘状态临时变量
  50. int id_hash,id_hash2,xLoca,i;//id 康托哈希下标值,xLoca 暂存x位置
  51.  
  52. tmp1=t;//初始状态
  53.  
  54. tmp2.s=sTarg;//目标状态
  55. tmp2.xLoca=;//目标状态x位置
  56.  
  57. id_hash=cantor_hash(tmp1.s);//初始状态
  58. visF[id_hash]=true;
  59. op[id_hash].idF=-;
  60. qF.push(tmp1);
  61.  
  62. id_hash=cantor_hash(tmp2.s);//目标状态
  63. visR[id_hash]=true;
  64. op[id_hash].idR=-;
  65. qR.push(tmp2);
  66.  
  67. while(!qF.empty()&&!qR.empty()){
  68. //正向bfs
  69. tmp1=qF.front();
  70. qF.pop();
  71. id_hash=cantor_hash(tmp1.s);
  72. if(visR[id_hash]){//反向bfs也访问过
  73. display(id_hash);
  74. id_hash2=id_hash;
  75. while(op[id_hash2].idR!=-){
  76. printf("%c",op[id_hash2].cR);
  77. id_hash2=op[id_hash2].idR;
  78. }
  79. printf("\n");
  80. return;
  81. }
  82. for(i=;i<;++i){
  83. if(i==&&tmp1.xLoca<)continue;
  84. if(i==&&tmp1.xLoca>)continue;
  85. if(i==&&tmp1.xLoca%==)continue;
  86. if(i==&&tmp1.xLoca%==)continue;
  87. xLoca=tmp1.xLoca+dir[i];
  88.  
  89. tmp2=tmp1;
  90. swap(tmp2.s[tmp1.xLoca],tmp2.s[xLoca]);
  91. id_hash2=cantor_hash(tmp2.s);
  92. if(!visF[id_hash2]){
  93. visF[id_hash2]=true;
  94. tmp2.xLoca=xLoca;
  95. op[id_hash2].idF=id_hash;
  96. op[id_hash2].cF=opF[i];
  97. qF.push(tmp2);
  98. }
  99. }
  100.  
  101. //反向bfs
  102. tmp1=qR.front();
  103. qR.pop();
  104. id_hash=cantor_hash(tmp1.s);
  105. if(visF[id_hash]){//正向bfs也访问过
  106. display(id_hash);
  107. id_hash2=id_hash;
  108. while(op[id_hash2].idR!=-){
  109. printf("%c",op[id_hash2].cR);
  110. id_hash2=op[id_hash2].idR;
  111. }
  112. printf("\n");
  113. return;
  114. }
  115. for(i=;i<;++i){
  116. if(i==&&tmp1.xLoca<)continue;
  117. if(i==&&tmp1.xLoca>)continue;
  118. if(i==&&tmp1.xLoca%==)continue;
  119. if(i==&&tmp1.xLoca%==)continue;
  120. xLoca=tmp1.xLoca+dir[i];
  121.  
  122. tmp2=tmp1;
  123. swap(tmp2.s[tmp1.xLoca],tmp2.s[xLoca]);
  124. id_hash2=cantor_hash(tmp2.s);
  125. if(!visR[id_hash2]){
  126. visR[id_hash2]=true;
  127. tmp2.xLoca=xLoca;
  128. op[id_hash2].idR=id_hash;
  129. op[id_hash2].cR=opR[i];
  130. qR.push(tmp2);
  131. }
  132. }
  133. }
  134. }
  135.  
  136. int main(){
  137. char str[];//串
  138. int len;//串长度
  139. int i,j,k;//k 第几个数码
  140. int ivsNum;//逆序数
  141. while(~scanf("%[^\n]",str)){
  142. getchar();//吸收回车
  143.  
  144. memset(visF,false,sizeof(visF));
  145. memset(visR,false,sizeof(visR));
  146.  
  147. len=strlen(str);
  148. t.s="";
  149. k=;//第几个数码
  150. for(i=;i<len;++i){//处理字符串
  151. if(str[i]!=' '){
  152. if(str[i]=='x'){
  153. t.s=t.s+'';
  154. t.xLoca=k;
  155. }
  156. else t.s=t.s+str[i];
  157. ++k;//
  158. }
  159. }
  160.  
  161. ivsNum=;//逆序数初始为0
  162. for(i=;i<;++i){
  163. if(t.s[i]=='')continue;
  164. for(j=;j<i;++j){
  165. if(t.s[j]=='')continue;
  166. if(t.s[j]>t.s[i])++ivsNum;
  167. }
  168. }
  169. if(ivsNum&)printf("unsolvable\n");//逆序数为奇数
  170. else dBfs();//双向bfs
  171. }
  172. return ;
  173. }

hdu 1043 Eight(双向bfs)的更多相关文章

  1. 2017多校第10场 HDU 6171 Admiral 双向BFS或者A*搜索

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6171 题意: 给你一个高度为6的塔形数组,你每次只能将0与他上下相邻的某个数交换,问最少交换多少次可以 ...

  2. HDU 1242 -Rescue (双向BFS)&amp;&amp;( BFS+优先队列)

    题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出 ...

  3. HDU 3085 Nightmare Ⅱ (双向BFS)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  4. HDU 3085 Nightmare Ⅱ 双向BFS

    题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...

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

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

  6. Nightmare Ⅱ HDU - 3085 (双向bfs)

    Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were tra ...

  7. ACM-BFS之Open the Lock——hdu1195(双向BFS)

    这道题的0基础版本号,暴力BFS及题目详情请戳:http://blog.csdn.net/lttree/article/details/24658031 上回书说道,要用双向BFS来尝试一下. 最终A ...

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

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

  9. Eight (HDU - 1043|POJ - 1077)(A* | 双向bfs+康拓展开)

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...

随机推荐

  1. set_include_path() &&get_include_path()用法

    function initialize(){    set_include_path(get_include_path().PATH_SEPARATOR . "core/");   ...

  2. (11)UML设计视图

    UML的词汇表包含三种构造块:事物.关系和图 事物:事物是对模型中最具有代表性的成分的抽象 关系:把事物结合在一起 图:图聚集了相关的事物 一.事物 UML中有4种事物 (1)结构事物 UML 模型中 ...

  3. js -- 侧边悬浮栏特效

    github: https://github.com/mybee/float-scroll-page #menu{width: 120px;height: auto; position: fixed; ...

  4. Mysql 性能优化20个原则(2)

    5. 在Join表的时候使用相当类型的例,并将其索引 如果你的应用程序有很多 JOIN 查询,你应该确认两个表中Join的字段是被建过索引的.这样,MySQL内部会启动为你优化Join的SQL语句的机 ...

  5. 配置 yum 源相关

    1. 修改yum配置 http://www.cnblogs.com/shuaixf/archive/2011/11/30/2268496.html 2. centos安装 epel 源 https:/ ...

  6. [Javascript] Use a custom sort function on an Array in Javascript

    Sorting in Javascript with sort uses lexical sorting by default, which means it will sort in alphabe ...

  7. Intel Edision —— 从SSH无法连接到systemd

    前言 原创文章,转载引用务必注明链接.如有疏漏,欢迎斧正. 最近在试用Wyliodrin,安装过程中出现了两个问题,一是无法使用SSH登录到Edison:二是EDISON磁盘的问题.分别涉及到syst ...

  8. ZOJ ACM 1314(JAVA)

    昨天做了几个题目.过于简单,就不在博客里面写了. 1314这道题也比較简单,写出来是由于我认为在这里有一个小技巧,对于时间复杂度和空间复杂度都比較节省. 这个题目类似哈希表的求解.可是更简单.刚拿到题 ...

  9. C#语法复习1

    一.C#与.net框架 .net是语言无关的. 程序的执行流程: .net兼容语言的源代码文件 .net兼容编译器 程序集(公共中间语言(CIL)common intermediate languag ...

  10. MYSQL时间戳的处理

    date为需要处理的参数(该参数是Unix 时间戳),可以是字段名,也可以直接是Unix 时间戳字符串 后面的 '%Y%m%d' 主要是将返回值格式化 例如: mysql>SELECT FROM ...