UVA_571
一开始没什么思路,后来看了别人的解题报告发现是用类似贪心的方式去做的。
由于这个题目没有限定倒水的次数,所以只要构造出一个可行解就可以,如果我们每次A是空的就加水,不空就向B倒,B满了之后就empty掉,这样在B中一定可以形成0-B的任意一个解。
后来自己简单的证明了一下。按这样去倒水的话,我们可以用(n*A)%B表示B中的水量,由于A与B互质,那么容易得到这个函数的最小周期是B,并且在一个周期内,我们易证明这个函数的值均是不同的,而一个周期内(准确来说要包含两个临界点)n的取值是0-B,那么对应的值也必然会恰好覆盖满0-B,因此这样我们就一定可以得到一个满足要求的操作序列。
#include<stdio.h>
#include<string.h>
int Ca, Cb, N;
void solve()
{
int i, j, k, a, b;
a = b = 0;
for(;;)
{
if(b == N)
{
printf("success\n");
break;
}
else if(b == Cb)
{
printf("empty B\n");
b = 0;
}
if(!a)
{
printf("fill A\n");
a = Ca;
}
printf("pour A B\n");
if(a + b > Cb)
{
a = a + b - Cb;
b = Cb;
}
else
{
b += a;
a = 0;
}
}
}
int main()
{
while(scanf("%d%d%d", &Ca, &Cb, &N) == 3)
{
solve();
}
return 0;
}