Eight

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10778    Accepted Submission(s):
2873
Special Judge

Problem 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 Output
ullddrurdllurdruldr
 
Source
 
Recommend
JGShining   |   We have carefully selected several
similar problems for you:  1044 1401 1104 1254 1732
 
 康托展开优化,代码自己写的过了,做EIGHTII的时候,发现别人bfs()很简单,而且map[4][2]写的看不懂。
 
  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<string>
  6. #include<queue>
  7. using namespace std;
  8.  
  9. struct node
  10. {
  11. bool flag;
  12. char str;
  13. int father;
  14. }hash[];
  15. struct st
  16. {
  17. char t[];
  18. };
  19. queue<st>Q;
  20. int ans[]={};
  21.  
  22. int ktzk(char *c)
  23. {
  24. int i,j,k,sum=;
  25. for(i=;i<=;i++)
  26. {
  27. k=;
  28. for(j=i+;j<=;j++)
  29. if(c[i]>c[j])
  30. k++;
  31. sum=sum+k*ans[-i];
  32. }
  33. return sum;
  34. }
  35. void bfs()
  36. {
  37. int i,k,num,val;
  38. struct st cur,t;
  39. k=ktzk("");
  40. hash[k].flag=true;
  41. hash[k].str='\0';
  42. hash[k].father=k;
  43.  
  44. strcpy(t.t,"");
  45. Q.push(t);
  46.  
  47. while(!Q.empty())
  48. {
  49. cur=Q.front();
  50. Q.pop();
  51. val=ktzk(cur.t);
  52. for(i=;i<=;i++)
  53. {
  54. if(cur.t[i]=='')
  55. {
  56. k=i;
  57. break;
  58. }
  59. }
  60. if(k!= && k!= && k!=)//rigth
  61. {
  62. t=cur;
  63. swap(t.t[k],t.t[k+]);
  64. num=ktzk(t.t);
  65. if(hash[num].flag==false)
  66. {
  67. hash[num].flag=true;
  68. hash[num].str='r';
  69. hash[num].father=val;
  70. Q.push(t);
  71. }
  72. }
  73. if(k!= && k!= && k!=)//left
  74. {
  75. t=cur;
  76. swap(t.t[k],t.t[k-]);
  77. num=ktzk(t.t);
  78. if(hash[num].flag==false)
  79. {
  80. hash[num].flag=true;
  81. hash[num].str='l';
  82. hash[num].father=val;
  83. Q.push(t);
  84. }
  85. }
  86. if(k>=)//u
  87. {
  88. t=cur;
  89. swap(t.t[k],t.t[k-]);
  90. num=ktzk(t.t);
  91. if(hash[num].flag==false)
  92. {
  93. hash[num].flag=true;
  94. hash[num].str='u';
  95. hash[num].father=val;
  96. Q.push(t);
  97. }
  98. }
  99. if(k<=)//D
  100. {
  101. t=cur;
  102. swap(t.t[k],t.t[k+]);
  103. num=ktzk(t.t);
  104. if(hash[num].flag==false)
  105. {
  106. hash[num].flag=true;
  107. hash[num].str='d';
  108. hash[num].father=val;
  109. Q.push(t);
  110. }
  111. }
  112. }
  113. }
  114. void prepare()
  115. {
  116. int i;
  117. for(i=;i<=;i++)
  118. {
  119. hash[i].flag=false;
  120. }
  121. for(i=;i<=;i++) ans[i]=ans[i-]*i;
  122. bfs();
  123. }
  124. int main()
  125. {
  126. prepare();
  127. char a[],b[],c[];
  128. bool tom[];
  129. int i,j,k,cur;
  130. while(gets(a))
  131. {
  132. k=strlen(a);
  133. b[]='\0';
  134. for(i=,j=;i<k;i++)
  135. {
  136. if(a[i]=='x' || (a[i]>=''&&a[i]<=''))
  137. {
  138. if(a[i]=='x')
  139. b[j]='';
  140. else b[j]=a[i];
  141. j++;
  142. }
  143. }
  144. memset(tom,false,sizeof(tom));
  145. for(i=;i<=;i++)
  146. {
  147. tom[b[i]-'']=true;
  148. }
  149. for(i=;i<=;i++)
  150. {
  151. if(tom[i]==false)
  152. break;
  153. }
  154. if(i<=){printf("unsolvable\n");continue;}
  155. cur=ktzk(b);
  156. if(hash[cur].flag==false)
  157. {
  158. printf("unsolvable\n");
  159. continue;
  160. }
  161. k=;
  162. while(hash[cur].father!=cur)
  163. {
  164. c[k]=hash[cur].str;
  165. k++;
  166. cur=hash[cur].father;
  167. }
  168. for(i=;i<=k-;i++)
  169. {
  170. if(c[i]=='u')printf("d");
  171. if(c[i]=='d')printf("u");
  172. if(c[i]=='l')printf("r");
  173. if(c[i]=='r')printf("l");
  174. }
  175. printf("\n");
  176. }
  177. return ;
  178. }

hdu 1043 八数码问题的更多相关文章

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

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

  2. HDU 1043 八数码(A*搜索)

    在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...

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

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

  4. HDU 1043 八数码问题的多种解法

    一.思路很简单,搜索.对于每一种状态,利用康托展开编码成一个整数.于是,状态就可以记忆了. 二.在搜索之前,可以先做个优化,对于逆序数为奇数的序列,一定无解. 三.搜索方法有很多. 1.最普通的:深搜 ...

  5. HDU 1043 八数码 Eight A*算法

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

  6. Eight hdu 1043 八数码问题 双搜

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

  7. hdu 1043 Eight 经典八数码问题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 The 15-puzzle has been around for over 100 years ...

  8. HDU 1043 Eight(八数码)

    HDU 1043 Eight(八数码) 00 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)   Problem Descr ...

  9. Hdu 1043 Eight (八数码问题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目描述: 3*3的格子,填有1到8,8个数字,还有一个x,x可以上下左右移动,问最终能否移动 ...

随机推荐

  1. go get golang.org/x/net 安装失败的解决方法!

    GO语言在github.com上建立了自己的项目,对应的包如果不能下载,那么可以到这里去下载,比如:"go get golang.org/x/net"不能下载这个包,那么我们可以访 ...

  2. jzoj5906

    我們首先發現,每一條邊都至少走1次,因為我們必須走到每一個節點按按鈕 如果我們不走一個節點,說明這個節點已經有傳送門了,但是必須走到這個節點開傳送門,矛盾 然後我們發現,每一條邊至多經過2次 如果我們 ...

  3. JSP知识汇总

    JSP知识汇总 一.简介 > HTML - HTML擅长显示一个静态的网页,但是不能调用Java程序. > Servlet - Servlet擅长调用Java程序和后台进行交互,但是它不擅 ...

  4. 基于Web实现网络拓扑图

    想想好像好久没用写博客了! 由于最近想跳槽了(ps:尽管公司挽留,提出一些异与往常的挽留“制度”,But确实已经死心了) ,发现前一段时间一些做Hadoop,和Spark同事时常来请教网络拓扑图的有关 ...

  5. Vue的实时时间转换Demo

    Vue的实时时间转换Demo time.html: <!DOCTYPE html> <html lang="en"> <head> <me ...

  6. arm处理器启动流程分析

    2440: 启动方式:nor , nand 地址布局: 启动流程: 开发板在上电后,会从0x0地址处运行. 如果从nor flash启动,则代码要放在nor 的0地址处: 如果从nand flash启 ...

  7. java.lang 类String

    方法摘要1  charcharAt(int index) 返回指定索引处的 char 值.               index - char 值的索引.2 string       concat( ...

  8. 终于完成了-- github.com/salomon1184/METP

  9. springMVC中ModelAndView学写笔记

    api介绍: 构造函数摘要 ModelAndView()           bean样式用法的默认构造函数:填充bean属性,而不是传递构造函数参数. ModelAndView(Object vie ...

  10. Linux下最常用的Shell命令的介绍

    Shell基础: 你可以通过打开Linux的terminal(终端)来执行Shell命令.Shell的种类有很多种,例如CSH,Bourne Shell,Korn Shell.在现在的大多数Linux ...