拨开云雾见月明—分析容器的倒水问题

     无意中看到一道挑战题目,难度系数一颗星,可是发现挑战的人很多,挑战成功的人反而不多。很是奇怪,于是细细看了看题目,发现它的初衷原来是如此回事儿。题目如下:      

     有两个容器,容积分别为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;
     }
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值