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 }

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值