POJ 1077 8数码问题(BFS)

Eight

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) :    Accepted Submission(s) : 
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 a description of a configuration of the 8 puzzle. The 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.
 

 

Sample Input
2 3 4 1 5 x 7 6 8
 

 

Sample Output
ullddrurdllurdruldr
 

 

Source
PKU
 

 

整个程序由以下部分组成:结点,cantor展开(当HASH函数用的),移动函数,BFS,输出函数

由于有调试的部分在里面而且移动函数也不是特别简洁所以显得特别长,BFS效率低下也只有在弱数据的POJ 1077可以过

  1 #include <iostream>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5 #include <stack>
  6 #include <stdio.h>
  7 
  8 #define MAX 500000
  9 
 10 char str[400000];
 11     int tot=0;
 12 
 13 using namespace std;
 14 
 15 struct Note
 16 {
 17     char s[9];//数码串
 18     int num;//第多少号
 19     int fa;//父结点是多少号
 20     char dir;//从父结点MOVE方向
 21 }note[MAX];
 22 
 23 queue<Note> q;
 24 
 25 int vis[MAX];
 26 
 27 int cantor(char* s)
 28 {
 29     int len=9;
 30 
 31     int sum=0;
 32     for(int i=0;i<len;i++)
 33     {
 34         int a=0;
 35         int b=1;
 36         for(int j=i+1;j<len;j++)
 37             if(s[j]<s[i])
 38             {
 39                 a=a+1;
 40             }
 41         //sum+=a*(8-i)!
 42         for(int k=1;k<len-i;k++)
 43         {
 44             b*=k;
 45         }
 46 
 47         sum+=a*b;
 48     }
 49 
 50     return sum;
 51 
 52 }
 53 
 54 int move4(char *s,int n)
 55 {
 56     //会对S进行改变
 57     //返回1表示进行了移动,返回0表示没有移动
 58     int pos;
 59     int len=9;
 60     if(n==1)//move up
 61     {
 62         for(int i=0;i<len;i++)
 63         {
 64             if(s[i]=='9')
 65             {
 66                 pos=i;
 67                 break;
 68             }
 69         }
 70         if(pos-3>=0)
 71         {
 72             s[pos]=s[pos-3]^s[pos];
 73             s[pos-3]=s[pos]^s[pos-3];
 74             s[pos]=s[pos]^s[pos-3];
 75 
 76             return 1;
 77         }
 78         else
 79             return 0;
 80     }
 81     if(n==2)//move down
 82     {
 83         for(int i=0;i<len;i++)
 84         {
 85             if(s[i]=='9')
 86             {
 87                 pos=i;
 88                 break;
 89             }
 90         }
 91         if(pos+3<9)
 92         {
 93             s[pos]=s[pos+3]^s[pos];
 94             s[pos+3]=s[pos]^s[pos+3];
 95             s[pos]=s[pos]^s[pos+3];
 96 
 97             return 1;
 98         }
 99         else
100             return 0;
101     }
102     if(n==3)//move left
103     {
104         for(int i=0;i<len;i++)
105         {
106             if(s[i]=='9')
107             {
108                 pos=i;
109                 break;
110             }
111         }
112         if(pos-1>=0&&(pos/3==(pos-1)/3))
113         {
114             s[pos]=s[pos-1]^s[pos];
115             s[pos-1]=s[pos]^s[pos-1];
116             s[pos]=s[pos]^s[pos-1];
117 
118             return 1;
119         }
120         else
121             return 0;
122     }
123     if(n==4)//move right
124     {
125         for(int i=0;i<len;i++)
126         {
127             if(s[i]=='9')
128             {
129                 pos=i;
130                 break;
131             }
132         }
133         if(pos+1<9&&(pos/3==(pos+1)/3))
134         {
135             s[pos]=s[pos+1]^s[pos];
136             s[pos+1]=s[pos]^s[pos+1];
137             s[pos]=s[pos]^s[pos+1];
138 
139             return 1;
140         }
141         else
142             return 0;
143     }
144 
145     return 0;
146 }
147 
148 int bfs()
149 {
150     while(!q.empty())
151     {
152         int ok=1;
153         Note t=q.front();
154         Note t2=q.front();
155         q.pop();
156         for(int i=0;i<8;i++)
157         {
158             if(t.s[i]-48==i+1&&t.s[8]=='9')
159                    ;
160             else
161                 {
162                     ok=0;
163                 }
164         }
165  //       cout<<"判断是否可以结束:  "<<ok<<endl;
166 
167         if(ok)
168         {
169             return t.fa;
170         }
171  //           cout<<"还要继续搜索。。。"<<endl;
172             t2=t;//cout<<"up up up\n";
173             if(move4(t2.s,1))
174             {
175    //             cout<<"向上走。。。"<<endl;
176 
177                 int k=cantor(t2.s);
178                 if(vis[k]==0)
179                 {
180  //                   cout<<"行。。。"<<endl;
181                     t2.dir='u';
182                     t2.fa=t.num;
183 /*
184                     cout<<"k: "<<k<<" fa:"<<t2.fa<<endl;
185                     for(int i=0;i<9;i++)
186                     {
187                         cout<<t2.s[i]<<" ";
188                         if((i+1)%3==0) cout<<endl;
189                     }
190                     cout<<t2.dir<<endl;
191 
192 */
193                     t2.num=k;
194                     note[k]=t2;
195                     q.push(t2);
196                     vis[k]=1;
197                 }
198   //              else cout<<"不行。。。"<<endl;
199             }
200             t2=t; // cout<<"down down down\n";
201             if(move4(t2.s,2))
202             {
203   //              cout<<"向下走。。。"<<endl;
204 
205                 int k=cantor(t2.s);
206                 if(vis[k]!=1)
207                 {
208                     t2.dir='d';
209                     t2.fa=t.num;
210   //                   cout<<"行。。。"<<endl;
211 /*
212                     cout<<"k: "<<k<<" fa:"<<t2.fa<<endl;
213                     for(int i=0;i<9;i++)
214                     {
215                         cout<<t2.s[i]<<" ";
216                         if((i+1)%3==0) cout<<endl;
217                     }
218                     cout<<t2.dir<<endl;
219 */
220                     t2.num=k;
221                     note[k]=t2;
222                     q.push(t2);
223                     vis[k]=1;
224                 }
225   //              else cout<<"不行。。。"<<endl;
226             }
227             t2=t; // cout<<"left left left\n";
228             if(move4(t2.s,3))
229             {
230   //              cout<<"向左走。。。"<<endl;
231 
232                 int k=cantor(t2.s);
233                 if(vis[k]!=1)
234                 {
235                     t2.dir='l';
236                     t2.fa=t.num;
237     //                 cout<<"行。。。"<<endl;
238 /*
239                     cout<<"k: "<<k<<" fa:"<<t2.fa<<endl;
240                     for(int i=0;i<9;i++)
241                     {
242                         cout<<t2.s[i]<<" ";
243                         if((i+1)%3==0) cout<<endl;
244                     }
245                     cout<<t2.dir<<endl;
246 
247   */                  t2.num=k;
248                     note[k]=t2;
249                     q.push(t2);
250                     vis[k]=1;
251                 }
252    //            else cout<<"不行。。。"<<endl;
253             }
254             t2=t; //cout<<"right right right\n";
255             if(move4(t2.s,4))
256             {
257    //             cout<<"向右走。。。"<<endl;
258 
259                 int k=cantor(t2.s);
260                 if(vis[k]!=1)
261                 {
262                     t2.dir='r';
263                     t2.fa=t.num;
264                     // cout<<"行。。。"<<endl;
265 
266 /*
267                     cout<<"k: "<<k<<" fa:"<<t2.fa<<endl;
268                     for(int i=0;i<9;i++)
269                     {
270                         cout<<t2.s[i]<<" ";
271                         if((i+1)%3==0) cout<<endl;
272                     }
273                     cout<<t2.dir<<endl;
274 */
275                     t2.num=k;
276                     note[k]=t2;
277                     q.push(t2);
278                     vis[k]=1;
279                 }
280   //              else cout<<"不行。。。"<<endl;
281             }
282 
283     }
284 
285     return -999;
286 }
287 
288 
289 void print (int p)
290 {
291     stack < char > stck;
292     while ( note[p].dir!='Q' )
293     {
294         stck.push(note[p].dir);
295         p = note[p].fa;
296     }
297     while ( !stck.empty() )
298     {
299         putchar ( stck.top() );
300         stck.pop();
301     }
302     putchar ('\n');
303 }
304 
305 
306 int main()
307 {
308     memset(vis,0,sizeof(vis));
309     Note t;
310     for(int i=0;i<9;i++)
311     {
312         char c;
313         cin>>c;
314         if(c=='x')
315         {
316             t.s[i]='9';
317         }
318         else t.s[i]=c;
319     }
320 
321     int k=cantor(t.s);
322     t.num=k;
323     t.fa=-998;
324     t.dir='Q';
325     note[k]=t;
326 
327     q.push(t);
328 
329     int B=bfs();
330     note[k].dir='Q';
331     note[k].fa=-998;
332     ///xxxxxx
333     if(B==-999)  cout<<"unsolvable"<<endl;
334 
335   //  cout<<"B:  "<<B<<endl;
336 
337     print(0);
338 
339     return 0;
340 }

 

 

posted @ 2013-04-13 11:24  码代码的猿猿  阅读(316)  评论(0编辑  收藏  举报