Jugs
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 4076 | Accepted: 2411 | Special Judge |
Description
In the movie "Die Hard 3", Bruce Willis and Samuel L. Jackson were confronted with the following puzzle. They were given a 3-gallon jug and a 5-gallon jug and were asked to fill the 5-gallon jug with exactly 4 gallons. This problem generalizes that puzzle.
You have two jugs, A and B, and an infinite supply of water. There are three types of actions that you can use: (1) you can fill a jug, (2) you can empty a jug, and (3) you can pour from one jug to the other. Pouring from one jug to the other stops when the first jug is empty or the second jug is full, whichever comes first. For example, if A has 5 gallons and B has 6 gallons and a capacity of 8, then pouring from A to B leaves B full and 3 gallons in A.
A problem is given by a triple (Ca,Cb,N), where Ca and Cb are the capacities of the jugs A and B, respectively, and N is the goal. A solution is a sequence of steps that leaves exactly N gallons in jug B. The possible steps are
fill A
fill B
empty A
empty B
pour A B
pour B A
success
where "pour A B" means "pour the contents of jug A into jug B", and "success" means that the goal has been accomplished.
You may assume that the input you are given does have a solution.
You have two jugs, A and B, and an infinite supply of water. There are three types of actions that you can use: (1) you can fill a jug, (2) you can empty a jug, and (3) you can pour from one jug to the other. Pouring from one jug to the other stops when the first jug is empty or the second jug is full, whichever comes first. For example, if A has 5 gallons and B has 6 gallons and a capacity of 8, then pouring from A to B leaves B full and 3 gallons in A.
A problem is given by a triple (Ca,Cb,N), where Ca and Cb are the capacities of the jugs A and B, respectively, and N is the goal. A solution is a sequence of steps that leaves exactly N gallons in jug B. The possible steps are
fill A
fill B
empty A
empty B
pour A B
pour B A
success
where "pour A B" means "pour the contents of jug A into jug B", and "success" means that the goal has been accomplished.
You may assume that the input you are given does have a solution.
Input
Input to your program consists of a series of input lines each defining one puzzle. Input for each puzzle is a single line of three positive integers: Ca, Cb, and N. Ca and Cb are the capacities of jugs A and B, and N is the goal. You can assume 0 < Ca <= Cb and N <= Cb <=1000 and that A and B are relatively prime to one another.
Output
Output from your program will consist of a series of instructions from the list of the potential output lines which will result in either of the jugs containing exactly N gallons of water. The last line of output for each puzzle should be the line "success". Output lines start in column 1 and there should be no empty lines nor any trailing spaces.
Sample Input
3 5 4 5 7 3
Sample Output
fill B pour B A empty A pour B A fill B pour B A success fill A pour A B fill A pour A B empty B pour A B success
1 /*注意:本题是让 b 中达到目标状态 用到队列 + 记忆化搜索 2 //代码一:纯模拟---从讨论区看见的,由于本题没有要求输出的结果是最少的操作次数,所以这种方法也是可以的 3 #include <iostream> 4 5 using namespace std; 6 7 int main() 8 { 9 int ca,cb,n; 10 while (cin >> ca >> cb >> n) 11 { 12 int bnow; 13 int b = 0; 14 while (b != n) 15 { 16 for (int i = 0;i <= (cb - b) / ca;i++) 17 { 18 cout << "fill A" << endl; 19 cout << "pour A B" << endl; 20 bnow = b + ca * (i + 1); 21 if (bnow == n) 22 { 23 break; 24 } 25 } 26 if (bnow == n) 27 { 28 break; 29 } 30 cout << "empty B" << endl; 31 int a; 32 a = ca - (cb - b) % ca; 33 cout << "pour A B" << endl; 34 b = a; 35 if (b == n) 36 { 37 break; 38 } 39 } 40 cout << "success" << endl; 41 } 42 return 0; 43 } 44 */ 45 /* 46 //代码二: 用STL队列,可以保证结果肯定是最少的操作次数-----搜索路径算法还未完成 47 #include <iostream> 48 #include <cstring> 49 //#include <queue> 50 51 using namespace std; 52 53 struct state 54 { 55 int a; 56 int b; 57 int opt; 58 int last_opt; 59 int tot_opt; 60 }; 61 char cmd[6][10] = {"fill A", "fill B", "empty A", "empty B", "pour A B", "pour B A"}; 62 bool visit[1001][1001]; 63 int path[200]; 64 int ca, cb, n; 65 66 67 int BFS(int sa, int sb, int steps) 68 { 69 queue <state> q; 70 front = tail = 0; 71 state t1, t2; 72 t1.a = 0; 73 t1.b = 0; 74 t1.opt = -1; 75 t1.last_opt = -1; 76 t1.tot_opt = 0; 77 q.push(t1); 78 while(!q.empty()) 79 { 80 t2 = q.front(); 81 q.pop(); 82 if(t2.b ==n) 83 { 84 。。。。。。。。 85 。。。。。。。。 86 // 因为用的是stl中的queue,所以这里还没想到应该咋实现才能回溯遍历所有的路径 87 。。。。。。。。 88 } 89 else 90 { 91 state t3; 92 if(t2.a != ca && !visit[ca][t2.b]) //fill A 93 { 94 t3.a = ca; 95 t3.b = t2.b; 96 t3.opt = 0; 97 t3.last_opt = t2.opt; 98 t3.tot_opt = t2.tot_opt + 1; 99 visit[ca][t2.b] = true; 100 q.push(t3); 101 } 102 if(t2.b != cb && !visit[t2.a][cb]) // fill B 103 { 104 t3.a = t2.a; 105 t3.b = cb; 106 t3.opt = 1; 107 t3.last_opt = t2.opt; 108 t3.tot_opt = t2.tot_opt + 1; 109 visit[t2.a][cb] = true; 110 q.push(t3); 111 } 112 if(t2.a != 0 && !visit[0][t2.b]) // empty A 113 { 114 t3.a = 0; 115 t3.b = t2.b; 116 t3.opt = 2; 117 t3.last_opt = t2.opt; 118 t3.tot_opt = t2.tot_opt + 1; 119 visit[0][t2.b] = true; 120 q.push(t3); 121 } 122 if(t2.b != 0 && !visit[t2.a][0]) // empty B 123 { 124 t3.a = t2.a; 125 t3.b = 0; 126 t3.opt = 3; 127 t3.last_opt = t2.opt; 128 t3.tot_opt = t2.tot_opt + 1; 129 visit[t2.a][0] = true; 130 q.push(t3); 131 } 132 if(sb != cb && t2.a != 0) // pour A to B 133 { 134 if(t2.a <= cb - t2.b) 135 { 136 t3.a = 0; 137 t3.b = t2.b + t2.a; 138 } 139 else 140 { 141 t3.a = t2.a - (cb - t2.b); 142 t3.b = cb; 143 } 144 t3.opt = 4; 145 t3.last_opt = t2.opt; 146 t3.tot_opt = t2.tot_opt + 1; 147 visit[t3.a][t3.b] = true; 148 q.push(t3); 149 } 150 if(t2.a != ca && cb != 0) // pour B to A 151 { 152 if(t2.b <= ca - t2.a) 153 { 154 t3.b = 0; 155 t3.a = t2.a + t2.b; 156 } 157 else 158 { 159 t3.a = ca; 160 t3.b = t2.b - (ca - t2.a); 161 } 162 t3.opt = 5; 163 t3.last_opt = t2.opt; 164 t3.tot_opt = t2.tot_opt + 1; 165 visit[t3.a][t3.b] = true; 166 q.push(t3); 167 } 168 } 169 } 170 } 171 172 int main() 173 { 174 while(cin >> ca >> cb >> n) 175 { 176 memset(visit, false, sizeof(visit)); 177 memset(path, 0, sizeof(path)); 178 visit[0][0] = true; 179 int tot_step = BFS(0, 0, 0); 180 for(int i = 1; i <= tot_step; ++i) 181 cout << cmd[path[i]] << endl; 182 cout << "success" <<endl; 183 } 184 return 0; 185 } 186 */ 187 //代码三:------AC 188 #include <iostream> 189 #include <cstring> 190 191 using namespace std; 192 193 struct state 194 { 195 int a; //记录当前a中的量 196 int b; //记录当前b中的量 197 int opt; //记录当前状态是由前一状态怎样得来的,即记录的是操作数----对应的是cmd数组的一维下标 198 int last_path; //记录上一步所在状态的队列下标,方便回溯查找路径 199 int tot_opt; //记录到底本状态总共用了多少步 200 }q[10000]; 201 char cmd[6][10] = {"fill A", "fill B", "empty A", "empty B", "pour A B", "pour B A"}; 202 bool visit[1001][1001]; 203 int path[200]; 204 int ca, cb, n; 205 206 207 int BFS(int sa, int sb, int steps) 208 { 209 int front, tail; 210 front = tail = 0; 211 state t1, t2; 212 t1.a = 0; 213 t1.b = 0; 214 t1.opt = -1; 215 t1.last_path = -1; 216 t1.tot_opt = 0; 217 q[tail++] = t1; 218 while(front != tail) 219 { 220 t2 = q[front++]; 221 if(t2.b == n) 222 { 223 state t = t2; 224 for(int i = t.tot_opt; i > 0; --i) 225 { 226 path[i] = t.opt; 227 t = q[t.last_path]; 228 } 229 return t2.tot_opt; 230 } 231 else 232 { 233 state t3; 234 if(t2.a != ca && !visit[ca][t2.b]) //fill A 235 { 236 t3.a = ca; 237 t3.b = t2.b; 238 t3.opt = 0; 239 t3.last_path = front - 1; 240 t3.tot_opt = t2.tot_opt + 1; 241 visit[ca][t2.b] = true; 242 q[tail++] = t3; 243 } 244 if(t2.b != cb && !visit[t2.a][cb]) // fill B 245 { 246 t3.a = t2.a; 247 t3.b = cb; 248 t3.opt = 1; 249 t3.last_path = front - 1; 250 t3.tot_opt = t2.tot_opt + 1; 251 visit[t2.a][cb] = true; 252 q[tail++] = t3; 253 } 254 if(t2.a != 0 && !visit[0][t2.b]) // empty A 255 { 256 t3.a = 0; 257 t3.b = t2.b; 258 t3.opt = 2; 259 t3.last_path = front - 1; 260 t3.tot_opt = t2.tot_opt + 1; 261 visit[0][t2.b] = true; 262 q[tail++] = t3; 263 } 264 if(t2.b != 0 && !visit[t2.a][0]) // empty B 265 { 266 t3.a = t2.a; 267 t3.b = 0; 268 t3.opt = 3; 269 t3.last_path = front - 1; 270 t3.tot_opt = t2.tot_opt + 1; 271 visit[t2.a][0] = true; 272 q[tail++] = t3;; 273 } 274 if(sb != cb && t2.a != 0) // pour A to B 275 { 276 if(t2.a <= cb - t2.b) 277 { 278 t3.a = 0; 279 t3.b = t2.b + t2.a; 280 } 281 else 282 { 283 t3.a = t2.a - (cb - t2.b); 284 t3.b = cb; 285 } 286 t3.opt = 4; 287 t3.last_path = front - 1; 288 t3.tot_opt = t2.tot_opt + 1; 289 visit[t3.a][t3.b] = true; 290 q[tail++] = t3; 291 } 292 if(t2.a != ca && cb != 0) // pour B to A 293 { 294 if(t2.b <= ca - t2.a) 295 { 296 t3.b = 0; 297 t3.a = t2.a + t2.b; 298 } 299 else 300 { 301 t3.a = ca; 302 t3.b = t2.b - (ca - t2.a); 303 } 304 t3.opt = 5; 305 t3.last_path = front - 1; 306 t3.tot_opt = t2.tot_opt + 1; 307 visit[t3.a][t3.b] = true; 308 q[tail++] = t3; 309 } 310 } 311 } 312 } 313 314 int main() 315 { 316 while(cin >> ca >> cb >> n) 317 { 318 memset(visit, false, sizeof(visit)); 319 memset(path, 0, sizeof(path)); 320 visit[0][0] = true; 321 int tot_step = BFS(0, 0, 0); 322 for(int i = 1; i <= tot_step; ++i) 323 cout << cmd[path[i]] << endl; 324 cout << "success" <<endl; 325 } 326 return 0; 327 }
功不成,身已退