Eight

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 18153 Accepted Submission(s): 4908

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

解决这道题目,有很多方法,比如双广,BFS打表,A*+简单估价函数,A*+曼哈顿距离,IDA*+曼哈顿距离。但是这些方法都是基于在康托展开的基础上,别的状态表示都会超时。关于康托展开给出一篇博客把

http://blog.csdn.net/Dacc123/article/details/50952079

还有这道题目在poj和hdu上的测试数据是不同的,hdu上的数据比较多吧,poj水一点。

双广,从起始和结尾同时bfs,用康托展开表示状态

hdu看数据的,有的时候是可以过的4960ms。双广还是效率比较低的,poj 188ms

  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <queue>
  8. #include <map>
  9. #include <string>
  10. using namespace std;
  11. struct Node
  12. {
  13. int a[3][3];
  14. int x,y;
  15. int state,id;
  16. Node(){};
  17. Node(int a[3][3],int x,int y,int state,int id)
  18. {
  19. this->id=id;
  20. this->x=x;
  21. this->y=y;
  22. this->state=state;
  23. memcpy(this->a,a,sizeof(this->a));
  24. }
  25. };
  26. queue<Node>q;
  27. string f[2][500000];
  28. int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
  29. int fac[10];
  30. int s[2];
  31. char m[2][5]={"udlr","durl"};
  32. char str[105];
  33. void facfun()
  34. {
  35. fac[0]=1;
  36. for(int i=1;i<=9;i++)
  37. fac[i]=fac[i-1]*i;
  38. }
  39. int kangtuo(int a[3][3])
  40. {
  41. int sum=0,num;
  42. for(int i=0;i<9;i++)
  43. {
  44. num=0;
  45. for(int j=i+1;j<9;j++)
  46. {
  47. if(a[i/3][i%3]>a[j/3][j%3])
  48. num++;
  49. }
  50. sum+=num*fac[8-i];
  51. }
  52. return sum;
  53. }
  54. bool isok(int a[3][3])
  55. {
  56. int num=0;
  57. for(int i=0;i<9;i++)
  58. {
  59. for(int j=i+1;j<9;j++)
  60. {
  61. if(a[i/3][i%3]!=9&&a[j/3][j%3]!=9&&a[i/3][i%3]>a[j/3][j%3])
  62. num++;
  63. }
  64. }
  65. return !(num&1);
  66. }
  67. void bfs(Node st,Node ed)
  68. {
  69. memset(f,0,sizeof(f));
  70. q.push(st);q.push(ed);
  71. s[1]=st.state;s[0]=ed.state;
  72. f[1][s[1]]=""; f[0][s[0]] = "";
  73. while(!q.empty())
  74. {
  75. Node term=q.front();
  76. q.pop();
  77. for(int i=0;i<4;i++)
  78. {
  79. int xx=term.x+dir[i][0];
  80. int yy=term.y+dir[i][1];
  81. if(xx<0||xx>=3||yy<0||yy>=3)
  82. continue;
  83. swap(term.a[xx][yy],term.a[term.x][term.y]);
  84. int state=kangtuo(term.a);
  85. if(!f[term.id][state][0])
  86. {
  87. if(term.id)
  88. f[term.id][state]=f[term.id][term.state]+m[term.id][i];
  89. else
  90. f[term.id][state]=m[term.id][i]+f[term.id][term.state];
  91. if(f[1-term.id][state][0])
  92. {
  93. cout<<f[1][state]<<f[0][state]<<endl;
  94. return;
  95. }
  96. else
  97. q.push(Node(term.a,xx,yy,state,term.id));
  98. }
  99. swap(term.a[xx][yy],term.a[term.x][term.y]);
  100. }
  101. }
  102. //printf("unsolvable\n");
  103. }
  104. int main()
  105. {
  106. while(gets(str))
  107. {
  108. while(!q.empty())
  109. q.pop();
  110. facfun();
  111. Node st;
  112. int len=strlen(str);
  113. int cot=0;
  114. for(int i=0;i<len;i++)
  115. {
  116. if(str[i]!=' ')
  117. {
  118. if(str[i]=='x')
  119. {
  120. st.a[cot/3][cot%3]=9;
  121. st.x=cot/3;st.y=cot%3;
  122. }
  123. else
  124. st.a[cot/3][cot%3]=str[i]-'0';
  125. cot++;
  126. }
  127. }
  128. st.id=1;st.state=kangtuo(st.a);
  129. Node ed;
  130. cot=1;
  131. for(int i=0;i<3;i++)
  132. for(int j=0;j<3;j++)
  133. ed.a[i][j]=cot++;
  134. ed.x=2;ed.y=2;ed.id=0;ed.state=kangtuo(ed.a);
  135. if(!isok(st.a))
  136. {
  137. printf("unsolvable\n");
  138. continue;
  139. }
  140. bfs(st,ed);
  141. }
  142. return 0;
  143. }

BFS打表:从结果往前面扫,把每一种状态到结果的步数记录下来。

hdu 109ms poj 989ms

  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <map>
  8. #include <queue>
  9. using namespace std;
  10. int fac[]={1,1,2,6,24,120,720,5040,40320};
  11. int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
  12. struct Node
  13. {
  14. int a[5][5];
  15. int posx;
  16. int posy;
  17. int sta;
  18. };
  19. queue<Node> q;
  20. bool vis[400000];
  21. int res[400000];
  22. int pre[400000];
  23. char s[100];
  24. int a1[100];
  25. int a2[10];
  26. map<int,char>m;
  27. int kt(Node s)
  28. {
  29. int cot=0;
  30. for(int i=1;i<=3;i++)
  31. for(int j=1;j<=3;j++)
  32. a2[++cot]=s.a[i][j];
  33. int sum=0,num;
  34. for(int i=1;i<=9;i++)
  35. {
  36. num=0;
  37. for(int j=i+1;j<=9;j++)
  38. {
  39. if(a2[i]>a2[j])
  40. num++;
  41. }
  42. sum+=num*fac[9-i];
  43. }
  44. return sum;
  45. }
  46. void bfs(Node a)
  47. {
  48. q.push(a);
  49. vis[0]=1;
  50. while(!q.empty())
  51. {
  52. Node term=q.front();
  53. q.pop();
  54. for(int i=0;i<4;i++)
  55. {
  56. int xx=term.posx+dir[i][0];
  57. int yy=term.posy+dir[i][1];
  58. if(xx<1||xx>3||yy<1||yy>3)
  59. continue;
  60. Node temp=term;
  61. swap(temp.a[temp.posx][temp.posy],temp.a[xx][yy]);
  62. temp.posx=xx;temp.posy=yy;
  63. int state=kt(temp);temp.sta=state;
  64. if(vis[state])
  65. continue;
  66. pre[state]=term.sta;
  67. res[state]=i;
  68. vis[state]=1;
  69. q.push(temp);
  70. }
  71. }
  72. }
  73. void fun(int term)
  74. {
  75. if(term==0)
  76. return;
  77. cout<<m[res[term]];
  78. fun(pre[term]);
  79. }
  80. int main()
  81. {
  82. m[0]='u';m[1]='d';m[2]='l';m[3]='r';
  83. int cnt=1;
  84. Node t;
  85. for(int i=1;i<=3;i++)
  86. for(int j=1;j<=3;j++)
  87. t.a[i][j]=cnt++;
  88. t.posx=3;t.posy=3;t.sta=0;
  89. memset(vis,0,sizeof(vis));
  90. vis[0]=1;
  91. bfs(t);
  92. while(gets(s))
  93. {
  94. int x,y;
  95. int len=strlen(s);
  96. int cot=0;
  97. Node t3;
  98. for(int i=0;i<len;i++)
  99. {
  100. if(s[i]!=' ')
  101. {
  102. cot++;
  103. if(cot%3==0) { x=cot/3; y=3;}
  104. else { x=cot/3+1; y=cot%3;}
  105. if(s[i]=='x')
  106. t3.a[x][y]=9;
  107. else
  108. t3.a[x][y]=s[i]-'0';
  109. }
  110. }
  111. int target=kt(t3);
  112. if(!vis[target])
  113. printf("unsolvable\n");
  114. else
  115. {
  116. fun(target);
  117. cout<<endl;
  118. }
  119. }
  120. return 0;
  121. }

A*+简单估价函数+优先队列 ,这里要加一个判断来对应unsolved,当初始状态的逆序数(除去要移动的版块)和目标状态的同偶或同奇,就一定可以到达,否则一定不能。

简单估价函数:可以以当前状态下,多少个数字的位置是不正确的,表示价值。

hdu 2964ms poj 0ms

  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <math.h>
  6. #include <queue>
  7. #include <stdio.h>
  8. #include <string>
  9. #include <map>
  10. using namespace std;
  11. #define MAX 400000
  12. struct Node
  13. {
  14. int a[3][3];//图的状态
  15. int x,y;//空格的位置
  16. int state;//康托展开
  17. int g,h;//估价函数g,h
  18. string s;//记录路径
  19. bool operator<(const Node a)const
  20. {
  21. return h==a.h?g>a.g:h>a.h;
  22. }
  23. };
  24. priority_queue<Node> q;
  25. int fac[10];
  26. int vis[MAX+5];
  27. int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
  28. map<int,char> m;
  29. char c[100];
  30. void facfun()
  31. {
  32. m[0]='d';m[1]='u';m[2]='r';m[3]='l';
  33. fac[0]=1;
  34. for(int i=1;i<=9;i++)
  35. fac[i]=fac[i-1]*i;
  36. }
  37. //康托展开
  38. int kangtuo(int a[3][3])
  39. {
  40. int sum=0,num;
  41. for(int i=0;i<9;i++)
  42. {
  43. num=0;
  44. for(int j=i+1;j<9;j++)
  45. {
  46. if(a[i/3][i%3]>a[j/3][j%3])
  47. num++;
  48. }
  49. sum+=num*fac[8-i];
  50. }
  51. return sum;
  52. }
  53. //简单估价函数
  54. int get(int a[3][3])
  55. {
  56. int num=0;
  57. for(int i=0;i<8;i++)
  58. {
  59. if(a[i/3][i%3]!=i+1)
  60. num++;
  61. }
  62. return num;
  63. }
  64. void bfs(Node st)
  65. {
  66. q.push(st);
  67. vis[st.state]=1;
  68. int sh=st.h;int sg=st.g;
  69. while(!q.empty())
  70. {
  71. Node temp;
  72. Node term=q.top();
  73. q.pop();
  74. if(term.state==0)
  75. {
  76. cout<<term.s<<endl;
  77. return;
  78. }
  79. for(int i=0;i<4;i++)
  80. {
  81. temp=term;
  82. int xx=temp.x+dir[i][0];
  83. int yy=temp.y+dir[i][1];
  84. if(xx<0||xx>2||yy<0||yy>2)
  85. continue;
  86. swap(temp.a[temp.x][temp.y],temp.a[xx][yy]);
  87. temp.x=xx;temp.y=yy;temp.s=term.s+m[i];
  88. temp.g=term.g+1;temp.h=get(temp.a);
  89. temp.state=kangtuo(temp.a);
  90. if(vis[temp.state])
  91. continue;
  92. vis[temp.state]=1;
  93. q.push(temp);
  94. }
  95. }
  96. printf("unsolvable\n");
  97. }
  98. bool isok(int a[3][3])
  99. {
  100. int num=0;
  101. for(int i=0;i<9;i++)
  102. {
  103. for(int j=i+1;j<9;j++)
  104. {
  105. if(a[i/3][i%3]!=9&&a[j/3][j%3]!=9&&a[i/3][i%3]>a[j/3][j%3])
  106. num++;
  107. }
  108. }
  109. if(!(num&1))
  110. return true;
  111. else
  112. return false;
  113. }
  114. int main()
  115. {
  116. while(gets(c))
  117. {
  118. facfun();
  119. while(!q.empty())
  120. {
  121. q.pop();
  122. }
  123. memset(vis,0,sizeof(vis));
  124. int len=strlen(c);
  125. Node start;
  126. int cot=0;
  127. for(int i=0;i<len;i++)
  128. {
  129. if(c[i]!=' ')
  130. {
  131. if(c[i]=='x')
  132. {
  133. start.a[cot/3][cot%3]=9;
  134. start.x=cot/3;start.y=cot%3;
  135. }
  136. else
  137. start.a[cot/3][cot%3]=c[i]-'0';
  138. cot++;
  139. }
  140. }
  141. start.g=0;start.h=get(start.a);start.state=kangtuo(start.a);
  142. start.s="";
  143. if(!isok(start.a))
  144. {
  145. printf("unsolvable\n");
  146. continue;
  147. }
  148. bfs(start);
  149. }
  150. return 0;
  151. }

A*+曼哈顿距离+优先队列

股价函数变成了曼哈顿距离

hdu 1450ms poj 0ms

  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <math.h>
  6. #include <queue>
  7. #include <stdio.h>
  8. #include <string>
  9. #include <map>
  10. using namespace std;
  11. #define MAX 400000
  12. struct Node
  13. {
  14. int a[3][3];//图的状态
  15. int x,y;//空格的位置
  16. int state;//康托展开
  17. int g,h;//估价函数g,h
  18. string s;//记录路径
  19. bool operator<(const Node a)const
  20. {
  21. return h==a.h?g>a.g:h>a.h;
  22. }
  23. };
  24. priority_queue<Node> q;
  25. int fac[10];
  26. int vis[MAX+5];
  27. int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
  28. map<int,char> m;
  29. char c[100];
  30. void facfun()
  31. {
  32. m[0]='d';m[1]='u';m[2]='r';m[3]='l';
  33. fac[0]=1;
  34. for(int i=1;i<=9;i++)
  35. fac[i]=fac[i-1]*i;
  36. }
  37. //康托展开
  38. int kangtuo(int a[3][3])
  39. {
  40. int sum=0,num;
  41. for(int i=0;i<9;i++)
  42. {
  43. num=0;
  44. for(int j=i+1;j<9;j++)
  45. {
  46. if(a[i/3][i%3]>a[j/3][j%3])
  47. num++;
  48. }
  49. sum+=num*fac[8-i];
  50. }
  51. return sum;
  52. }
  53. //简单估价函数
  54. int get(int a[3][3])
  55. {
  56. int num=0;
  57. for(int i=0;i<3;i++)
  58. {
  59. for(int j=0;j<3;j++)
  60. {
  61. int x=(a[i][j]-1)/3;
  62. int y=(a[i][j]-1)%3;
  63. num+=abs(x-i)+abs(y-j);
  64. }
  65. }
  66. return num;
  67. }
  68. void bfs(Node st)
  69. {
  70. q.push(st);
  71. vis[st.state]=1;
  72. int sh=st.h;int sg=st.g;
  73. while(!q.empty())
  74. {
  75. Node temp;
  76. Node term=q.top();
  77. q.pop();
  78. if(term.state==0)
  79. {
  80. cout<<term.s<<endl;
  81. return;
  82. }
  83. for(int i=0;i<4;i++)
  84. {
  85. temp=term;
  86. int xx=temp.x+dir[i][0];
  87. int yy=temp.y+dir[i][1];
  88. if(xx<0||xx>2||yy<0||yy>2)
  89. continue;
  90. swap(temp.a[temp.x][temp.y],temp.a[xx][yy]);
  91. temp.x=xx;temp.y=yy;temp.s=term.s+m[i];
  92. temp.g=term.g+1;temp.h=get(temp.a);
  93. temp.state=kangtuo(temp.a);
  94. if(vis[temp.state])
  95. continue;
  96. vis[temp.state]=1;
  97. q.push(temp);
  98. }
  99. }
  100. printf("unsolvable\n");
  101. }
  102. bool isok(int a[3][3])
  103. {
  104. int num=0;
  105. for(int i=0;i<9;i++)
  106. {
  107. for(int j=i+1;j<9;j++)
  108. {
  109. if(a[i/3][i%3]!=9&&a[j/3][j%3]!=9&&a[i/3][i%3]>a[j/3][j%3])
  110. num++;
  111. }
  112. }
  113. if(!(num&1))
  114. return true;
  115. else
  116. return false;
  117. }
  118. int main()
  119. {
  120. while(gets(c))
  121. {
  122. facfun();
  123. while(!q.empty())
  124. {
  125. q.pop();
  126. }
  127. memset(vis,0,sizeof(vis));
  128. int len=strlen(c);
  129. Node start;
  130. int cot=0;
  131. for(int i=0;i<len;i++)
  132. {
  133. if(c[i]!=' ')
  134. {
  135. if(c[i]=='x')
  136. {
  137. start.a[cot/3][cot%3]=9;
  138. start.x=cot/3;start.y=cot%3;
  139. }
  140. else
  141. start.a[cot/3][cot%3]=c[i]-'0';
  142. cot++;
  143. }
  144. }
  145. start.g=0;start.h=get(start.a);start.state=kangtuo(start.a);
  146. start.s="";
  147. if(!isok(start.a))
  148. {
  149. printf("unsolvable\n");
  150. continue;
  151. }
  152. bfs(start);
  153. }
  154. return 0;
  155. }

HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)的更多相关文章

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

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

  2. hdu 1043 pku poj 1077 Eight (BFS + 康拓展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 http://poj.org/problem?id=1077 Eight Time Limit: 1000 ...

  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. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

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

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

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

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

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

  7. HDU 1815, POJ 2749 Building roads(2-sat)

    HDU 1815, POJ 2749 Building roads pid=1815" target="_blank" style="">题目链 ...

  8. HDU 1686 Oulipo / POJ 3461 Oulipo / SCU 2652 Oulipo (字符串匹配,KMP)

    HDU 1686 Oulipo / POJ 3461 Oulipo / SCU 2652 Oulipo (字符串匹配,KMP) Description The French author George ...

  9. HDU 1816, POJ 2723 Get Luffy Out(2-sat)

    HDU 1816, POJ 2723 Get Luffy Out pid=1816" target="_blank" style="">题目链接 ...

随机推荐

  1. LINUX下CPU Load Average的一点研究

    背景: 公司的某个系统工作在基于Linux的Cent OS下,一个host下同时连接了许多client, 最近某台Host总是显示CPU Load Average过高,我们单纯的以为是CPU的占用过高 ...

  2. UVa 10633 - Rare Easy Problem

    题目:给定一个数N.去掉末尾的数变成M.如今已知N-M,确定N. 分析:数论.简单题. 设N = 10*a + b { 当中0 ≤ b ≤ 9 }.则M = a: N - M = N - a = 9* ...

  3. preventDefault

    e.preventDefault()阻止事件默认行为 例如: $("a").click(function (e) {   alert("默认行为被禁止喽"); ...

  4. [转]lsof详解

    lsof是一个功能强大的诊断工具,它可以通过进程与打开的文件进行联系,可以列出一个进程打开的所有文件信息. 1 寻找与打开的文件相关联的进程通过指定文件,可以发现正在使用这个文件的进程# lsof / ...

  5. 详解MathType快捷键使用技巧

    巧妙使用MathType数学公式编辑器可加快数学符号的录入速度和效率,这将节约大量的时间成本,本教程将详解MathType快捷键使用的诸多技巧. 在MathType界面,将鼠标轻轻的放在某个符号上,在 ...

  6. 如何用MathType编辑集合运算符号

    在涉及到集合的运算中,有交并且几种常见的运算,这在数学问题中也是很常见的公式.在用MathType编辑这些符号时,该怎么编辑呢?下面就介绍MathType集合运算符号的编辑方法. 具体操作过程如下: ...

  7. 【Matlab】运动目标检测之“帧差法”

    videoObj = VideoReader('4.avi');%读视频文件 nframes = get(videoObj, 'NumberOfFrames');%获取视频文件帧个数 : nframe ...

  8. 面试题:谈谈如何优化MYSQL数据库查询

    1.优化数据类型 MySQL中数据类型有多种,如果你是一名DBA,正在按照优化的原则对数据类型进行严格的检查,但开发人员可能会选择他们认为最简单的方案,以加快编码速度,或者选择最明显的选择,因此,你可 ...

  9. c语言常用数据类型转换整理

    你要发送原始数据流 还是 格式化输出? 如果是格式化 按原子说的 ,用sprintf / printf; 如果发送原始内存数据流, 可按下面发送, 发送 #define BYTE0(pointer) ...

  10. [转]ASP.NET MVC 5– 使用Wijmo MVC 5模板1分钟创建应用

    开始使用 使用ComponentOne Studio for ASP.NET Wijmo制作MVC5应用程序,首先要做的是安装Studio for ASP.NET Wijmo . 测试环境 VS201 ...