题意:就是八数码问题,给你开始的串和结束的串,问你从开始到结束的最短且最小的变换序列是什么

分析:我们可以预处理打表,这里的这个题可以和HDU1430魔板那个题采取一样的做法

预处理打表,因为八数码问题实际上是每个小块位置的变化,上面的数字只是用来标记位置的,

所以通过映射将初末序列进行置换就好了,然后因为每次的x字符的置换位置不一样

所以需要以123456789这个初始串打9遍表就好了733ms

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <vector>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <string>
  7. #include <cmath>
  8. #include <queue>
  9. using namespace std;
  10. const int N=;
  11. int fac[]= {,,,,,,,,,};
  12. int aim;
  13. int cantor(char s[])
  14. {
  15. int ans=;
  16. for(int i=,j=; i<=; ++i,--j)
  17. {
  18. int tmp=;
  19. for(int k=i+; k<=; ++k)
  20. if(s[i]>s[k])++tmp;
  21. ans+=(tmp*fac[j]);
  22. }
  23. return ans;
  24. }
  25. struct Node
  26. {
  27. char s[];
  28. int hs;
  29. };
  30. struct asd
  31. {
  32. bool vis;
  33. char c;
  34. int pre;
  35. }o[][];
  36. queue<Node>q;
  37. void bfs(int pos)
  38. {
  39. Node a;
  40. for(int i=; i<=; ++i)
  41. a.s[i]=''+i;
  42. aim=a.hs=cantor(a.s);
  43. o[pos][a.hs].vis=;
  44. q.push(a);
  45. while(!q.empty())
  46. {
  47. a=q.front();
  48. q.pop();
  49. int now=a.hs;
  50. int x;
  51. for(int i=; i<=; ++i)
  52. if(a.s[i]==''+pos)x=i;
  53. if(x+<)
  54. {
  55. bool flag=;
  56. swap(a.s[x],a.s[x+]);
  57. a.hs=cantor(a.s);
  58. if(o[pos][a.hs].vis)
  59. flag=;
  60. if(!flag)
  61. {
  62. o[pos][a.hs].vis=;
  63. o[pos][a.hs].c='d';
  64. o[pos][a.hs].pre=now;
  65. q.push(a);
  66. }
  67. swap(a.s[x],a.s[x+]);
  68. }
  69. if(x%!=)
  70. {
  71. bool flag=;
  72. swap(a.s[x],a.s[x-]);
  73. a.hs=cantor(a.s);
  74. if(o[pos][a.hs].vis)
  75. flag=;
  76. if(!flag)
  77. {
  78. o[pos][a.hs].vis=;
  79. o[pos][a.hs].c='l';
  80. o[pos][a.hs].pre=now;
  81. q.push(a);
  82. }
  83. swap(a.s[x],a.s[x-]);
  84. }
  85. if(x%)
  86. {
  87. bool flag=;
  88. swap(a.s[x],a.s[x+]);
  89. a.hs=cantor(a.s);
  90. if(o[pos][a.hs].vis)
  91. flag=;
  92. if(!flag)
  93. {
  94. o[pos][a.hs].vis=;
  95. o[pos][a.hs].c='r';
  96. o[pos][a.hs].pre=now;
  97. q.push(a);
  98. }
  99. swap(a.s[x],a.s[x+]);
  100. }
  101. if(x->)
  102. {
  103. bool flag=;
  104. swap(a.s[x],a.s[x-]);
  105. a.hs=cantor(a.s);
  106. if(o[pos][a.hs].vis)
  107. flag=;
  108. if(!flag)
  109. {
  110. o[pos][a.hs].vis=;
  111. o[pos][a.hs].c='u';
  112. o[pos][a.hs].pre=now;
  113. q.push(a);
  114. }
  115. swap(a.s[x],a.s[x-]);
  116. }
  117. }
  118. }
  119. char s[],t[];
  120. string res;
  121. void getres(int u,int pos)
  122. {
  123. while(u!=aim)
  124. {
  125. res=res+o[pos][u].c;
  126. u=o[pos][u].pre;
  127. }
  128. }
  129. char mat[];
  130. int main()
  131. {
  132. for(int i=;i<;++i)
  133. for(int j=;j<=;++j)
  134. o[j][i].vis=;
  135. for(int i=;i<=;++i)
  136. bfs(i);
  137. int T,cas=;
  138. scanf("%d",&T);
  139. while(T--)
  140. {
  141. scanf("%s%s",s+,t+);
  142. int flag;
  143. for(int i=;i<=;++i)
  144. {
  145. if(s[i]=='X')s[i]='',flag=i;
  146. if(t[i]=='X')t[i]='';
  147. mat[s[i]-'']=i+'';
  148. }
  149. for(int i=;i<=;++i)
  150. t[i]=mat[t[i]-''];
  151. int ans=cantor(t);
  152. res.clear();
  153. getres(ans,flag);
  154. printf("Case %d: %d\n",++cas,res.size());
  155. reverse(res.begin(),res.end());
  156. cout<<res<<endl;
  157. }
  158. return ;
  159. }

HDU 3567 Eight II BFS预处理的更多相关文章

  1. HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二

    类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...

  2. HDU 3567 Eight II(八数码 II)

    HDU 3567 Eight II(八数码 II) /65536 K (Java/Others)   Problem Description - 题目描述 Eight-puzzle, which is ...

  3. HDU 3533 Escape(BFS+预处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533 题目大意:给你一张n* m的地图,人在起点在(0,0)要到达终点(n,m)有k(k<=10 ...

  4. HDU - 1430 魔板 (bfs预处理 + 康托)

    对于该题可以直接预处理初始状态[0, 1, 2, 3, 4, 5, 6, 7]所有可以到达的状态,保存到达的路径,直接打印答案即可. 关于此处的状态转换:假设有初始状态为2,3,4,5,0,6,7,1 ...

  5. HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3

    http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过, ...

  6. HDU 3567 Eight II

    Eight II Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 3 ...

  7. hdu 1430 魔板 (BFS+预处理)

    Problem - 1430 跟八数码相似的一题搜索题.做法可以是双向BFS或者预处理从"12345678"开始可以到达的所有状态,然后等价转换过去直接回溯路径即可. 代码如下: ...

  8. POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)

    思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...

  9. HDU 4856 Tunnels(BFS+状压DP)

    HDU 4856 Tunnels 题目链接 题意:给定一些管道.然后管道之间走是不用时间的,陆地上有障碍.陆地上走一步花费时间1,求遍历全部管道须要的最短时间.每一个管道仅仅能走一次 思路:先BFS预 ...

随机推荐

  1. HttpClient抓取网页内容简单介绍

    版本HttpClient3.1 1.GET方式 第一步.创建一个客户端,类似于你用浏览器打开一个网页 HttpClient httpClient = new HttpClient(); 第二步.创建一 ...

  2. Qt智能指针简明说明

    下面的智能指针分别对应boost库,Qt库,c++11的智能指针 boost::scoped_ptr  QScopedPointer unique_ptr 在其生命期结束后会自动删除它所指的对象(确定 ...

  3. [转载]iOS本地推送-备用

    第一步:创建本地推送// 创建一个本地推送UILocalNotification *notification = [[[UILocalNotification alloc] init] autorel ...

  4. bnuoj 20838 Item-Based Recommendation (模拟)

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=20838 [题意]: 有点长,略. [code]: #include <iostream> ...

  5. linux usermod修改用户所在组方法

    usermod 用户名 -g 组名 -g<群组> 修改用户所属的群组. -G<群组> 修改用户所属的附加群组.

  6. tomcat 设置默认编码格式

    在tomcat目录下 conf文件夹下的server.xml中: <Connector port="80" protocol="HTTP/1.1"     ...

  7. 使用程序获取整型数据和浮点型数据在内存中的表示---gyy整理

    使用程序获取整型数据和浮点型数据在内存中的表示. C++中整型(int).短整型(short int).单精度浮点数(float).双精度浮点数(double)在内存中所占字节数不同,因此取值范围也不 ...

  8. WPF中动态添加xaml资源文件

    一.新建一个资源文件,然后设置其Build Actoin(生成操作)为Resource(资源): 二.在App.xaml.cs的StartUp事件或者是你需要的时机代码段写上如下代码: Resourc ...

  9. Fisher's exact test( 费希尔精确检验)

    Fisher's exact test[1][2][3] is a statistical significance test used in the analysis ofcontingency t ...

  10. 无效的 URI: 未能分析证书颁发机构/主机

    出 现该错误的原因是URL中少了一个斜杠,正常的URL是“http:”后边有两个斜杠,而我在修改配置文件中的URL的IP地址部分时,不小心删掉了一个 斜杠,例如:http:/blog.csdn.net ...