您的位置:首页 > 其它

POJ1606 HDU1415 UVA571 UVALive5502 Jugs【倒水+模拟】

2017-12-31 22:18 316 查看
Jugs

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5163 Accepted: 2987 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

Source
South Central USA 1997

问题链接POJ1606 HDU1415 UVA571 UVALive5502 Jugs


问题简述:(略)

问题分析

  这个问题是典型的倒水问题。倒水问题本质上就是不定方程,通常用扩展欧几里得算法来求解。

  由于题目保证有解,所以就用模拟法来实现。实际上也只能用模拟法实现,因为这个题需要输出的是倒水的过程,所以不模拟也不行。

程序说明:(略)
题记:(略)

参考链接:(略)

AC的C语言程序如下:

/* POJ1606 HDU1415 UVA571 UVALive5502 Jugs */

#include<stdio.h>
int main()
{
int ca, cb, n, a, b;

while(~scanf("%d%d%d", &ca, &cb, &n)) {
if(cb == n) {
/* B桶容量为目标水量,灌满B桶即可 */
printf("fill B\n");
} else if(ca == n) {
/* A桶容量为目标水量,先灌满A桶,然后将A桶中的水倒入B桶即可 */
printf("fill A\n");
printf("pour A B\n");
} else {
a = b = 0;
if(ca < n) {
/* 当A桶容量小于目标容量时,采取灌B桶倒到A桶策略 */
for(;;) {
if(b == 0) {
b = cb;
printf("fill B\n");
} else if(b > ca - a) {
/* B桶水量大于当前A桶容量,则将A桶倒满 */
b -= ca - a;
a = ca;
printf("pour B A\n");
} else {
/* B桶水量小于等于当前A桶容量,则将B桶水全部倒入A桶 */
a += b;
b = 0;
printf("pour B A\n");
}

if(b == n)
/* 倒完水后,若B桶水量达到目标水量则退出循环 */
break;
else if(ca == a) {
/* A桶已满则清空A桶 */
a = 0;
printf("empty A\n");
}
}
} else { /* ca >= n */
/* 当A桶容量大于等于n目标容量时,采取灌A桶倒到B桶策略 */
for(;;) {
if(a == 0) {
a = ca;
printf("fill A\n");
} else if(a > cb - b) {
/* A桶水量大于当前B桶容量,则将A桶倒满 */
a -= cb - b;
b = cb;
printf("pour A B\n");
} else {
/* A桶水量小于等于当前B桶容量,则将A桶水全部倒入B桶 */
b += a;
a = 0;
printf("pour A B\n");
}

if(b == n)
/* B桶水量达到目标水量则退出循环 */
break;
else if(b == cb) {
/* B桶已满则清空B桶 */
b = 0;
printf("empty B\n");
}
}
}
}
printf("success\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: