1. 程式人生 > >UVa-1604 Cubic Eight-Puzzle

UVa-1604 Cubic Eight-Puzzle

這是一份單向BFS一定會T的程式碼,挖坑等寫完雙向bfs再貼程式碼

  1 #include <bits/stdc++.h>
  2 #define _for(i,a,b) for(int i = (a);i < (b);i ++)
  3 using namespace std;
  4 struct cell
  5 {
  6     int t;
  7     int f;
  8 };
  9 
 10 typedef cell State[9];
 11 const int maxstate = 1000000;
 12 State st[maxstate],goal;
13 int dist[maxstate]; 14 15 const int dx[] = {-1,1,0,0}; 16 const int dy[] = {0,0,1,-1}; 17 18 bool equ(State s) 19 { 20 _for(i,0,9) 21 if(s[i].t != goal[i].t) return false; 22 return true; 23 } 24 25 bool limit(int x,int y) 26 { 27 return x>=0&&x<3
&&y>=0&&y<3; 28 } 29 30 set<int> vis; 31 void init_lookup_table() {vis.clear();} 32 bool try_to_insert(int s) 33 { 34 int v = 0; 35 _for(i,0,9) 36 { 37 if(st[s][i].t<0) 38 v = v*10+9; 39 else 40 v = v*10
+(st[s][i].t*3)+st[s][i].f; 41 } 42 if(vis.count(v)) return false; 43 vis.insert(v); 44 return true; 45 } 46 47 int bfs() 48 { 49 init_lookup_table(); 50 int front = 1,rear = 2; 51 while(front<rear) 52 { 53 State& s = st[front]; 54 cout << dist[front] << endl; 55 if(equ(s)) return front; 56 int z; 57 for(z = 0;z < 9;z ++) if(s[z].t<0) break; 58 int x = z/3,y = z%3; 59 _for(d,0,4) 60 { 61 int newx = x+dx[d]; 62 int newy = y+dy[d]; 63 int newz = newx*3+newy; 64 if(limit(newx,newy)) 65 { 66 State& t = st[rear]; 67 memcpy(&t,&s,sizeof(s)); 68 if(newx==x) 69 t[z] = (cell){3-s[newz].t-s[newz].f,s[newz].f}; 70 else if(newy==y) 71 t[z] = (cell){s[newz].f,s[newz].t}; 72 t[newz] = (cell){-1,-1}; 73 dist[rear] = dist[front]+1; 74 if(try_to_insert(rear)) rear ++; 75 } 76 } 77 front ++; 78 } 79 return -1; 80 } 81 82 int main() 83 { 84 int tx,ty; 85 while(scanf("%d%d",&tx,&ty)==2&&tx!=0) 86 { 87 _for(i,0,9) st[1][i] = (cell){0,1}; 88 st[1][(ty-1)*3+tx-1] = (cell){-1,-1}; 89 _for(i,0,9) 90 { 91 char c; 92 cin >> c; 93 if(c=='E') goal[i].t = -1; 94 else if(c=='W') goal[i].t = 0; 95 else if(c=='R') goal[i].t = 1; 96 else if(c=='B') goal[i].t = 2; 97 } 98 int ans = bfs(); 99 if(ans>0) printf("%d\n",dist[ans]); 100 else printf("-1\n"); 101 return 0; 102 } 103 return 0; 104 }