BFS入门,经典倒水问题,想当年在UVa上做的第一道BFS,今天在POJ上拿来复习一下。
拓展队列时注意去掉一些不必要的情况和细节:
1.空杯子不能向外倒水
2.水从A倒入B后,B水满或不满分情况考虑。据说可以一个式子解决……我是没一个式子解决掉,就分开写了。
3.水满的杯子不能再向里倒水
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <queue> 5 6 using namespace std; 7 8 const int MAXN = 30000; 9 10 bool vis[MAXN]; 11 int A, B, C; 12 int head[MAXN]; 13 int step[MAXN]; 14 int cnt[MAXN]; 15 16 int BFS() 17 { 18 memset( vis, false, sizeof(vis) ); 19 queue<int> Q; 20 21 int st = 0; 22 Q.push(st); 23 24 vis[st] = true; 25 head[st] = -1; 26 cnt[st] = 0; 27 28 while ( !Q.empty() ) 29 { 30 int cur = Q.front(); 31 Q.pop(); 32 33 int AA = cur / 100; 34 int BB = cur % 100; 35 36 if ( AA == C || BB == C ) return cur; 37 int temp; 38 39 if ( AA != A ) // fill A 40 { 41 temp = A * 100 + BB ; 42 43 if ( !vis[temp] ) 44 { 45 vis[temp] = true; 46 head[temp] = cur; 47 step[temp] = 1; 48 cnt[temp] = cnt[cur] + 1; 49 Q.push( temp ); 50 } 51 } 52 53 if ( AA != 0 ) 54 { 55 if ( BB != B ) // pour A to B 56 { 57 if ( AA + BB <= B ) temp = AA + BB; 58 else temp = ( AA - ( B - BB ) ) * 100 + B; 59 60 if ( !vis[temp] ) 61 { 62 vis[temp] = true; 63 head[temp] = cur; 64 step[temp] = 2; 65 cnt[temp] = cnt[cur] + 1; 66 Q.push( temp ); 67 } 68 } 69 70 temp = BB; //drop A 71 72 if ( !vis[temp] ) 73 { 74 vis[temp] = true; 75 head[temp] = cur; 76 step[temp] = 3; 77 cnt[temp] = cnt[cur] + 1; 78 Q.push( temp ); 79 } 80 } 81 82 if ( BB != B ) // fill B 83 { 84 temp = AA * 100 + B ; 85 86 if ( !vis[temp] ) 87 { 88 vis[temp] = true; 89 head[temp] = cur; 90 step[temp] = 4; 91 cnt[temp] = cnt[cur] + 1; 92 Q.push( temp ); 93 } 94 } 95 96 if ( BB != 0 ) 97 { 98 if ( AA != A ) // pour B to A 99 { 100 if ( AA + BB <= A ) temp = ( AA + BB ) * 100; 101 else temp = A * 100 + BB - ( A - AA ); 102 103 if ( !vis[temp] ) 104 { 105 vis[temp] = true; 106 head[temp] = cur; 107 step[temp] = 5; 108 cnt[temp] = cnt[cur] + 1; 109 Q.push(temp); 110 } 111 } 112 113 temp = AA * 100; // drop B 114 if ( !vis[temp] ) 115 { 116 vis[temp] = true; 117 head[temp] = cur; 118 step[temp] = 6; 119 cnt[temp] = cnt[cur] + 1; 120 Q.push( temp ); 121 } 122 } 123 } 124 125 return -1; 126 } 127 128 void DFS( int cur ) 129 { 130 if ( cur == -1 ) return; 131 DFS( head[cur] ); 132 switch( step[cur] ) 133 { 134 case 1: puts("FILL(1)"); break; 135 case 2: puts("POUR(1,2)"); break; 136 case 3: puts("DROP(1)"); break; 137 case 4: puts("FILL(2)"); break; 138 case 5: puts("POUR(2,1)"); break; 139 case 6: puts("DROP(2)"); break; 140 } 141 return; 142 } 143 144 int main() 145 { 146 while ( ~scanf( "%d%d%d", &A, &B, &C ) ) 147 { 148 int ans = BFS(); 149 if ( ans != -1 ) 150 { 151 printf( "%d\n", cnt[ans] ); 152 DFS( ans ); 153 } 154 else puts("impossible"); 155 } 156 return 0; 157 }