Eight hdu 1043 poj 1077

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 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 = 1000003;  
  7 typedef int State[9];  
  8 State st[maxn];  
  9 int goal[] = {1, 2, 3, 4, 5, 6, 7, 8, 0};  
 10 int dx[] = {-1, 1,  0, 0};  
 11 int dy[] = { 0, 0, -1, 1};  
 12 int head[maxn], nxt[maxn], fa[maxn];  
 13 char dir[maxn];  
 14   
 15 int Hash(State s)       //哈希函数  
 16 {  
 17     int ret = 0, i;  
 18     for(i = 0; i < 9; i++) ret = ret * 10 + 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 != -1; e = nxt[e])  
 26     {  
 27         if(memcmp(st[e], st[rear], sizeof(st[e])) == 0) return 0;  
 28     }  
 29     nxt[rear] = head[h];  
 30     head[h] = rear;  
 31     return 1;  
 32 }  
 33   
 34 int bfs()       //遍历  
 35 {  
 36     int frt = 1, rear = 2, i, z;  
 37     while(frt < rear)  
 38     {  
 39         State& s = st[frt];  
 40         if(memcmp(s, goal, sizeof(s)) == 0) return frt;  
 41         for(z = 0; s[z] != 0; z++);  
 42         int x = z / 3;  
 43         int y = z % 3;  
 44         for(i = 0; i < 4; i++)  
 45         {  
 46             int newx = x + dx[i];  
 47             int newy = y + dy[i];  
 48             int newz = 3 * newx + newy;  
 49             if(newx >= 0 && newx < 3 && newy >= 0 && newy < 3)  
 50             {  
 51                 State& news = st[rear];  
 52                 memcpy(news, s, sizeof(s));  
 53                 news[z] = s[newz];  
 54                 news[newz] = 0;  
 55                 if(try_to_insert(rear))     //注意这里的路径输出的方式
 56                 {  
 57                     fa[rear] = frt;  
 58                     switch(i)  
 59                     {  
 60                         case 0: dir[rear] = 'u'; break;  
 61                         case 1: dir[rear] = 'd'; break;  
 62                         case 2: dir[rear] = 'l'; break;  
 63                         case 3: dir[rear] = 'r'; break;  
 64                         default: break;  
 65                     }  
 66                     rear++;  
 67                 }  
 68             }  
 69         }  
 70         frt++;  
 71     }  
 72     return 0;  
 73 }  
 74   
 75 void print(int i)       //输出  
 76 {  
 77     if(fa[i] == -1) return;  
 78     print(fa[i]);  
 79     cout<<dir[i];  
 80 }  
 81   
 82 int main()  
 83 {  
 84     char c[10];  
 85     int i, ret;  
 86     while(cin>>c[0]>>c[1]>>c[2]>>c[3]>>c[4]>>c[5]>>c[6]>>c[7]>>c[8])  
 87     {  
 88         for(i = 0; i < 9; i++) st[1][i] = c[i] == 'x' ? 0 : (int)(c[i]-'0');  
 89         memset(head, -1, sizeof(head));  
 90         fa[1] = -1;  
 91         ret = bfs();  
 92         if(ret)  
 93         {  
 94             print(ret);  
 95         }  
 96         else cout<<"unsolvable";  
 97         cout<<endl;  
 98     }  
 99     return 0;  
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 = 362900;
 20 int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};
 21 int dx[] = {1,0,-1,0},dy[] = {0,1,0,-1};//drul
 22 char ind[5] = "uldr";//与上面相反
 23 string path[maxn];//记录路径
 24 bool vis[maxn];
 25 int aim = 46233;//123456780 的康拓展开
 26 
 27 struct node
 28 {
 29     int s[9];  //记录状态
 30     int sit0;  //0 的位置
 31     int val;   //康拓展开的值
 32     string path;  // 路径
 33 };
 34 
 35 int cant(int s[])  //康拓展开
 36 {
 37     int code = 0;
 38     for(int i = 0; i < 9; i++)
 39     {
 40         int cnt = 0;
 41         for(int  j= i+1 ; j < 9; j++)
 42         {
 43             if(s[i] > s[j])
 44             {
 45                 cnt++;
 46             }
 47         }
 48         code += fac[8-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 = 0 ; i < 8;i++)
 59       cnt1.s[i] = i+1;
 60     cnt1.s[8] = 0;
 61     cnt1.sit0 = 8;
 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 / 3;
 72         int y = cnt1.sit0 % 3;
 73         for(int i = 0; i < 4; i++)
 74         {
 75             int nx = x + dx[i];
 76             int ny = y + dy[i];
 77             int nz = nx * 3 + ny;
 78             if(nx < 0 || nx >2 || ny <0 || ny >2)
 79                continue;
 80             cnt2 = cnt1;
 81             cnt2.s[cnt1.sit0] = cnt2.s[nz];
 82             cnt2.s[nz] = 0;
 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[0] = 0;
106             st.sit0 = 0;
107         }
108         else
109         st.s[0] = t - '0';
110         for(int i = 1; i< 9; i++)
111         {
112             cin >> t;
113             if(t == 'x')
114             {
115                 st.s[i] = 0;
116                 st.sit0 = i;
117             }
118             else
119              st.s[i] = t -'0';
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 0;
130 }

 

 
 
posted @ 2016-07-22 22:38  PrayG  阅读(309)  评论(0编辑  收藏  举报