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:
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:
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.
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
is described by this list:
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 }