http://acm.pku.edu.cn/JudgeOnline/problem?id=1606
/**
* <problem>
*
* Jugs
* 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
*
* </problem>
*
* @author bbflyerwww
*/
#include<stdio.h>
#include<string.h>
#define MAX 10000
char s[][10] = {"fill A",
"fill B",
"empty A",
"empty B",
"pour A B",
"pour B A",
"success"
};
char rs[MAX][10];
int k;
int ca, cb, n;
int main()
{
int va, vb;
while(scanf("%d %d %d", &ca, &cb, &n) != EOF) {
//init some parameters
va = 0;
vb = 0;
k = -1;
//kernel
while(1) {
if(va == 0) {
//fill A while va == 0
va = ca;
k ++;
strcpy(rs[k], s[0]);
} else {
//do something else while va != 0
if(va > cb - vb) {
// va > cb - vb
va = va - (cb - vb);
vb = cb;
//pour A to B
k ++;
strcpy(rs[k], s[4]);
//break while vb == n notice that vb = cb now
if(vb == n) goto end;//break;
//empty B while vb != n
vb = 0;
k++;
strcpy(rs[k], s[3]);
} else {
// va < cb - vb
vb += va;
va = 0;
//pour A to B
k ++;
strcpy(rs[k], s[4]);
//break while vb == n notice that vb may be not full
if(vb == n) goto end;//break;
}
}
}
end:
//success
k++;
strcpy(rs[k], s[6]);
//show the result
for(int i = 0; i <= k; i++)
printf("%s/n", rs[i]);
}
return 0;
}
附加: 灌水定理
如果有n个壶容积分别为A1,A2,……,An(Ai均为大于0的整数)
设w为另一大于0的整数。则用此n个壶可倒出w升水的充要条件为:
1)w小于等于A1+A2+……+An;
2)w可被(A1,A2,……,An)(这n个数的最大公约数)整除。