题目来自庞果
有两个容器,容积分别为A升和B升,有无限多的水,现在需要C升水。 我们还有一个足够大的水缸,足够容纳C升水。起初它是空的,我们只能往水缸里倒入水,而不能倒出。 可以进行的操作是: 把一个容器灌满; 把一个容器清空(容器里剩余的水全部倒掉,或者倒入水缸); 用一个容器的水倒入另外一个容器,直到倒出水的容器空或者倒入水的容器满。 问是否能够通过有限次操作,使得水缸最后恰好有C升水。 输入:三个整数A, B, C,其中 0 < A , B, C <= 1000000000 输出:0或1,表示能否达到要求。 函数头部: c语言:1表示可以,0表示不可以 int can(int a,int b,int c); c++语言: true表示可以,false表示不可以 bool can(int a,int b,int c); java语言:true表示可以,false表示不可以 public class Main { public static boolean can(int a,int b,int c); }
算法描述
初步看到这个题目,这是一个标准的倒水问题,各大公司的面试题上面出现了很多版本了。如果看过算法的书,这是一个扩展的欧几里得算法。
就是看 A*x+B*y=M这个方程有没有x,y的整数解的问题,代码非常简单,基本上照搬扩展欧几里得算法就可以了。
不明白的可以看看欧几里得算法,说得很明白了。简单的说,就是有这么一条定律:
定理
如果求出最大公约数以后,再用C对这个公约数取模,如果为0表示满足要求,否则就不行
public class Main {
public static boolean can(int a,int b,int c){
int res;
res=mod(a,b);
if(c%res==0)
return true;
else
return false;
}
private static int mod(int a,int b){
if(b==0){
return a;
}
else
return mod(b,a%b);
}
public static void main(String[] args) {
System.out.println(can(10,3,70));
}
}