POJ-1606 Jugs


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.

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 }

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM