UVa-1604 Cubic Eight-Puzzle
Posted asurudo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 ",dist[ans]); 100 else printf("-1 "); 101 return 0; 102 } 103 return 0; 104 }
用优先队列改了改,加了个减枝,10秒内能出单个样例了,但肯定还是T没跑
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 struct State 11 { 12 cell c[9]; 13 int d; 14 }; 15 16 const int maxstate = 1000000; 17 State st,goal; 18 int dist[maxstate]; 19 20 const int dx[] = {-1,1,0,0}; 21 const int dy[] = {0,0,1,-1}; 22 23 int diff(State s) 24 { 25 int cnt = 0; 26 _for(i,0,9) 27 { 28 if(s.c[i].t != goal.c[i].t) cnt ++; 29 } 30 return cnt; 31 } 32 33 bool limit(int x,int y) 34 { 35 return x>=0&&x<3&&y>=0&&y<3; 36 } 37 38 set<int> vis; 39 void init_lookup_table() 40 { 41 vis.clear(); 42 } 43 bool try_to_insert(State s) 44 { 45 int v = 0; 46 _for(i,0,9) 47 { 48 if(s.c[i].t<0) 49 v = v*10+9; 50 else 51 v = v*10+(s.c[i].t*3)+s.c[i].f; 52 } 53 if(vis.count(v)) return false; 54 vis.insert(v); 55 return true; 56 } 57 58 struct cmp 59 { 60 bool operator () (State a,State b) 61 { 62 if(a.d==b.d) 63 { 64 int aa = diff(a); 65 int bb = diff(b); 66 return aa>bb; 67 } 68 else 69 return a.d>b.d; 70 } 71 }; 72 73 int bfs() 74 { 75 init_lookup_table(); 76 priority_queue<State,vector<State>,cmp> q; 77 st.d = 0; 78 q.push(st); 79 while(!q.empty()) 80 { 81 State s = q.top(); 82 q.pop(); 83 if(diff(s)+s.d>31) continue; 84 if(!diff(s)) return s.d; 85 int z; 86 for(z = 0; z < 9; z ++) if(s.c[z].t<0) break; 87 int x = z/3,y = z%3; 88 _for(d,0,4) 89 { 90 int newx = x+dx[d]; 91 int newy = y+dy[d]; 92 int newz = newx*3+newy; 93 if(limit(newx,newy)) 94 { 95 State t; 96 memcpy(&t,&s,sizeof(s)); 97 if(newx==x) 98 t.c[z] = (cell) 99 { 100 3-s.c[newz].t-s.c[newz].f,s.c[newz].f 101 }; 102 else if(newy==y) 103 t.c[z] = (cell) 104 { 105 s.c[newz].f,s.c[newz].t 106 }; 107 t.c[newz] = (cell) 108 { 109 -1,-1 110 }; 111 t.d = s.d+1; 112 if(try_to_insert(t)) q.push(t); 113 } 114 } 115 } 116 return -1; 117 } 118 119 int main() 120 { 121 int tx,ty; 122 while(scanf("%d%d",&tx,&ty)==2&&tx!=0) 123 { 124 _for(i,0,9) st.c[i] = (cell) 125 { 126 0,1 127 }; 128 st.c[(ty-1)*3+tx-1] = (cell) 129 { 130 -1,-1 131 }; 132 _for(i,0,9) 133 { 134 char c; 135 cin >> c; 136 if(c==‘E‘) goal.c[i].t = -1; 137 else if(c==‘W‘) goal.c[i].t = 0; 138 else if(c==‘R‘) goal.c[i].t = 1; 139 else if(c==‘B‘) goal.c[i].t = 2; 140 } 141 int ans = bfs(); 142 if(ans>=0) printf("%d ",ans); 143 else printf("-1 "); 144 return 0; 145 } 146 return 0; 147 }
以上是关于UVa-1604 Cubic Eight-Puzzle的主要内容,如果未能解决你的问题,请参考以下文章
UVa 1604 Eight Cubic-Puzzle 优化方案
习题 7-9 UVA-1604Cubic Eight-Puzzle
HDU-6216 A Cubic number and A Cubic Number[二分]