无意中看到一道挑战题目,难度系数一颗星,可是发现挑战的人很多,挑战成功的人反而不多。很是奇怪,于是细细看了看题目,发现它的初衷原来是如此回事儿。题目如下:
有两个容器,容积分别为A升和B升,有无限多的水,现在需要C升水。 我们还有一个足够大的水缸,足够容纳C升水。起初它是空的,我们只能往水缸里倒入水,而不能倒出。 可以进行的操作是: 把一个容器灌满; 把一个容器清空(容器里剩余的水全部倒掉,或者倒入水缸); 用一个容器的水倒入另外一个容器,直到倒出水的容器空或者倒入水的容器满。 问是否能够通过有限次操作,使得水缸最后恰好有C升水。 输入:三个整数A, B, C,其中 0 < A , B, C <= 1000000000 输出:0或1,表示能否达到要求。
这道题的意思就是根据A,B,C三个容器的容量,判断用A和B两个定容容器能否量够C升的水。A,B可以量够,从特殊情况考虑有三种基本情况,即①C%A==0;②C%B==0;③C%|A-B|==0,组合为一般式为:
i*A+j*B+k*|A-B|=C ,由题的一般性,不妨假设A>B,则上式简化为(i+k)*A+(j-k)*B=C。设x=i+k;y=j-k;继续简化为A*x+B*y=C。
到此,我们就可以明白该题的实质就是要我们判断是否存在整数x,y使得给定系数A,B,C满足等式:A*x+B*y=C。
我们知道,这样的二元一次方程存在整数解,则有C%gcd(A,B)==0,其中gcd(A,B)函数为求A,B的最大公约数,我们可以通过辗转相除法来解决。相关代码如下:
int can(int a,int b,int c) { if(c<=1000000000){ int d=gcd(a,b); if(c%d==0) return 1; else return 0; } else return 0; } int gcd(int a,int b){ if(b==0) return a; while(b!=0){ int r=b; b=a%b; a=r; } }