题意:
A、B两个瓶子,容积分别为ca,cb。ca和cb互质且0<ca<=cb。有三种操作:
1、fill 倒满某个瓶子
2、empty 清空某个瓶子
3、pour c d 将c瓶子中的水倒入d瓶子
问怎样经过若干次操作使得B瓶子中的水的体积为N(N<=cb且保证一定有解)。
算法:
x*ca mod cb = r(1<=x<cb)由于ca与cb互质,所以ca不能整除cb,x也不能整除cb,
这样x*ca也不能整除cb,故上式中r!=0.
可推出x1!=x2时,r1!=r2。
反证法证明:如果当x1!=x2时,r1 = r2,那么存在
x1*ca mod cb = r1
x2*ca mod cb = r2
使得(x1-x2)*ca mod cb = 0与r!=0矛盾。
故假设不成立。
那么,当x从1取到cb-1,r的所有可能也会枚举到(1到cb-1),而n<=cb,故一定能取到n的值。
这题的策略是:
如果A为空,则fill。如果A不为空则pour A B。如果B满则empty B。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int ca,cb,n;
while(scanf("%d%d%d",&ca,&cb,&n)!=EOF)
{
int ta = 0,tb = 0;
while(tb!=n)
{
if(tb == cb)
{
tb = 0;
printf("empty B\n");
}
if(ta==0)
{
ta = ca;
printf("fill A\n");
}
else
{
if(tb+ta<cb)
{
tb = tb+ta;
ta = 0;
}
else
{
ta = (tb+ta)%cb;
tb = cb;
}
printf("pour A B\n");
}
}
printf("success\n");
}
return 0;
}