Description

The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as:

  1. 1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 x

where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:

  1. 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
    5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
    9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
    13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
    r-> d-> r->

The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.

Input

You will receive, several descriptions of configuration of the 8 puzzle. One description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle

1 2 3
x 4 6
7 5 8

is described by this list:

1 2 3 x 4 6 7 5 8

Output

You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line. Do not print a blank line between cases.

Sample Input

2 3 4 1 5 x 7 6 8

Sample Input

2 3 4 1 5 x 7 6 8
题意 : 就是8数码问题,主要时搜索的路径寻找问题,把'x'转换为0,然后把当前这些数都存储为1个状态
分析: 这道题有两道相同的,分别是HDU和POJ,HDU上的数据加强了比POJ更麻烦。。
POJ:正向搜索就好(简单)
  1. #include <iostream>
  2. #include <cstring>
  3.  
  4. using namespace std;
  5.  
  6. const int maxn = ;
  7. typedef int State[];
  8. State st[maxn];
  9. int goal[] = {, , , , , , , , };
  10. int dx[] = {-, , , };
  11. int dy[] = { , , -, };
  12. int head[maxn], nxt[maxn], fa[maxn];
  13. char dir[maxn];
  14.  
  15. int Hash(State s) //哈希函数
  16. {
  17. int ret = , i;
  18. for(i = ; i < ; i++) ret = ret * + s[i];
  19. return ret % maxn;
  20. }
  21.  
  22. bool try_to_insert(int rear) //插入哈希表
  23. {
  24. int h = Hash(st[rear]);
  25. for(int e = head[h]; e != -; e = nxt[e])
  26. {
  27. if(memcmp(st[e], st[rear], sizeof(st[e])) == ) return ;
  28. }
  29. nxt[rear] = head[h];
  30. head[h] = rear;
  31. return ;
  32. }
  33.  
  34. int bfs() //遍历
  35. {
  36. int frt = , rear = , i, z;
  37. while(frt < rear)
  38. {
  39. State& s = st[frt];
  40. if(memcmp(s, goal, sizeof(s)) == ) return frt;
  41. for(z = ; s[z] != ; z++);
  42. int x = z / ;
  43. int y = z % ;
  44. for(i = ; i < ; i++)
  45. {
  46. int newx = x + dx[i];
  47. int newy = y + dy[i];
  48. int newz = * newx + newy;
  49. if(newx >= && newx < && newy >= && newy < )
  50. {
  51. State& news = st[rear];
  52. memcpy(news, s, sizeof(s));
  53. news[z] = s[newz];
  54. news[newz] = ;
  55. if(try_to_insert(rear))    //注意这里的路径输出的方式
  56. {
  57. fa[rear] = frt;
  58. switch(i)
  59. {
  60. case : dir[rear] = 'u'; break;
  61. case : dir[rear] = 'd'; break;
  62. case : dir[rear] = 'l'; break;
  63. case : dir[rear] = 'r'; break;
  64. default: break;
  65. }
  66. rear++;
  67. }
  68. }
  69. }
  70. frt++;
  71. }
  72. return ;
  73. }
  74.  
  75. void print(int i) //输出
  76. {
  77. if(fa[i] == -) return;
  78. print(fa[i]);
  79. cout<<dir[i];
  80. }
  81.  
  82. int main()
  83. {
  84. char c[];
  85. int i, ret;
  86. while(cin>>c[]>>c[]>>c[]>>c[]>>c[]>>c[]>>c[]>>c[]>>c[])
  87. {
  88. for(i = ; i < ; i++) st[][i] = c[i] == 'x' ? : (int)(c[i]-'');
  89. memset(head, -, sizeof(head));
  90. fa[] = -;
  91. ret = bfs();
  92. if(ret)
  93. {
  94. print(ret);
  95. }
  96. else cout<<"unsolvable";
  97. cout<<endl;
  98. }
  99. return ;
  100. }

HDU : 这道题时多组输入,所以不能向上面一样在线写,而是要从最终状态开始倒着把所有状态搜索一遍,之后只需要输入初始状态打表判断输出路径即可;

  学习到的知识有两个:bfs()路径查找类 + 康拓展开,路径的输出:

  1. /*************************************************************************
  2. > File Name: search.cpp
  3. > Author : PrayG
  4. > Mail: 996930051@qq,com
  5. > Created Time: 2016年07月20日 星期三 10时56分09秒
  6. ************************************************************************/
  7.  
  8. #include<iostream>
  9. #include<cstdio>
  10. #include<cstring>
  11. #include<string>
  12. #include<queue>
  13. #include<algorithm>
  14. #include<map>
  15. #include<stack>
  16. #include<set>
  17. #include<cmath>
  18. using namespace std;
  19. const int maxn = ;
  20. int fac[] = {,,,,,,,,,};
  21. int dx[] = {,,-,},dy[] = {,,,-};//drul
  22. char ind[] = "uldr";//与上面相反
  23. string path[maxn];//记录路径
  24. bool vis[maxn];
  25. int aim = ;//123456780 的康拓展开
  26.  
  27. struct node
  28. {
  29. int s[]; //记录状态
  30. int sit0;  //0 的位置
  31. int val;   //康拓展开的值
  32. string path;  // 路径
  33. };
  34.  
  35. int cant(int s[])  //康拓展开
  36. {
  37. int code = ;
  38. for(int i = ; i < ; i++)
  39. {
  40. int cnt = ;
  41. for(int j= i+ ; j < ; j++)
  42. {
  43. if(s[i] > s[j])
  44. {
  45. cnt++;
  46. }
  47. }
  48. code += fac[-i] * cnt;
  49. }
  50. return code;
  51. }
  52.  
  53. void bfs()
  54. {
  55. memset(vis,false,sizeof(vis));
  56. queue<node> que;
  57. node cnt1,cnt2;
  58. for(int i = ; i < ;i++)
  59. cnt1.s[i] = i+;
  60. cnt1.s[] = ;
  61. cnt1.sit0 = ;
  62. //printf("aim = %d\n",aim);
  63. cnt1.val = aim;
  64. cnt1.path = "";
  65. path[aim] = "";
  66. que.push(cnt1);
  67. while(!que.empty())
  68. {
  69. cnt1 = que.front();
  70. que.pop();
  71. int x = cnt1.sit0 / ;
  72. int y = cnt1.sit0 % ;
  73. for(int i = ; i < ; i++)
  74. {
  75. int nx = x + dx[i];
  76. int ny = y + dy[i];
  77. int nz = nx * + ny;
  78. if(nx < || nx > || ny < || ny >)
  79. continue;
  80. cnt2 = cnt1;
  81. cnt2.s[cnt1.sit0] = cnt2.s[nz];
  82. cnt2.s[nz] = ;
  83. cnt2.sit0 = nz;
  84. cnt2.val = cant(cnt2.s);
  85. if(!vis[cnt2.val])
  86. {
  87. vis[cnt2.val] = true;
  88. cnt2.path = ind[i] + cnt1.path;
  89. que.push(cnt2);
  90. path[cnt2.val] = cnt2.path;
  91. }
  92. }
  93.  
  94. }
  95. }
  96.  
  97. int main()
  98. {
  99. bfs();
  100. char t;
  101. while(cin >> t)
  102. {
  103. node st;
  104. if(t == 'x'){
  105. st.s[] = ;
  106. st.sit0 = ;
  107. }
  108. else
  109. st.s[] = t - '';
  110. for(int i = ; i< ; i++)
  111. {
  112. cin >> t;
  113. if(t == 'x')
  114. {
  115. st.s[i] = ;
  116. st.sit0 = i;
  117. }
  118. else
  119. st.s[i] = t -'';
  120. }
  121. st.val = cant(st.s);
  122. if(vis[st.val])
  123. {
  124. cout << path[st.val] << endl;
  125. }
  126. else
  127. cout << "unsolvable" << endl;
  128. }
  129. return ;
  130. }
 
 

Eight hdu 1043 poj 1077的更多相关文章

  1. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  2. HDU 1043 & POJ 1077 Eight(康托展开+BFS | IDA*)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  3. 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 ...

  4. Eight POJ - 1077 HDU - 1043 八数码

    Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...

  5. HDU - 1043 - Eight / POJ - 1077 - Eight

    先上题目: Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  6. HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)

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

  7. HDU 3695 / POJ 3987 Computer Virus on Planet Pandora(AC自动机)(2010 Asia Fuzhou Regional Contest)

    Description Aliens on planet Pandora also write computer programs like us. Their programs only consi ...

  8. hdu 2844 poj 1742 Coins

    hdu 2844 poj 1742 Coins 题目相同,但是时限不同,原本上面的多重背包我初始化为0,f[0] = 1;用位或进行优化,f[i]=1表示可以兑成i,0表示不能. 在poj上运行时间正 ...

  9. HDU 1043 八数码(八境界)

    看了这篇博客的讲解,挺不错的.http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 判断无解的情况(写完七种境界才发现有直接判 ...

随机推荐

  1. * ? 【a-z】【0-9】通配符 学习

    通配符顾名思义就是通用的匹配信息的符号,比如星号(*)就是代表匹配零个或多个字符,问号(?)是代表匹配单个字符,中括号内加上数字[0-9]代表匹配单个阿拉伯数字的字符,而中括号内加上字母[abc]则是 ...

  2. ztree实现根节点单击事件,显示节点信息

    这段时间在维护公司的项目,去年做的项目里面有ztree树的例子,想起之前还没有开始写博客,一些知识点也无从找起,要新加一个右击节点事件,折腾了半天,其中也包含了一些知识点,稍稍做了一些demo. zT ...

  3. 题解 UVA12206 【Stammering Aliens】

    终于A了这道题啊(坑啊) 教练说:这道题不能用map吧,复杂度不一个O(nlogn)吗 于是我就一直想不出来,然后看题解代码,一看就是map... 所以我就在想,那复杂度是不是也不是O(nlogn)呢 ...

  4. IDEA中编写脚本并运行shell脚本

    IDEA中编写脚本并运行shell脚本     来自 <https://blog.csdn.net/u012443641/article/details/81295999>

  5. String spilt时转义特殊字符【转】

    在使用String.split方法分隔字符串时,分隔符如果用到一些特殊字符,可能会得不到我们预期的结果. 我们经常使用public String[] split(String regex)方法来拆分一 ...

  6. 【转】C#正则表达式教程和示例

    [转]C#正则表达式教程和示例 有一段时间,正则表达式学习很火热很潮流,当时在CSDN一天就能看到好几个正则表达式的帖子,那段时间借助论坛以及Wrox Press出版的<C#字符串和正则表达式参 ...

  7. mysql-过程与函数

    一.过程与函数简介 过程与函数是命名的PL/SQL块(也是用户的方案对象),被编译后存储在数据库中,以备执行.因此,其他PL/SQL块可以按名称来使用他们.所以可以将商业逻辑.企业规划写成函数或过程保 ...

  8. Windows server 2008 布署FTP服务器实例(适用于阿里云)!

    Windows server 2008 布署FTP服务器实例(适用于阿里云). 1.打开管理.配置-用户-新建用户,如:ftp_user,并设置password.选择永只是期和password不能更改 ...

  9. [poj 2480] Longge's problem 解题报告 (欧拉函数)

    题目链接:http://poj.org/problem?id=2480 题目大意: 题解: 我一直很欣赏数学题完美的复杂度 #include<cstring> #include<al ...

  10. 美国人教你这样用Google,你真的会变特工

    转自微博:黑客师: 用了这么久的谷歌,今天才发现. 第一篇 在搜索框上输入:“indexof/”inurl:lib 再按搜索你将进入许多图书馆,并且一定能下载自己喜欢的书籍. 在搜索框上输入:“ind ...