水壶问题解法和原理解析

文章目录

问题描述

有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?

如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。

你允许:

  1. 装满任意一个水壶
  2. 清空任意一个水壶
  3. 从一个水壶向另外一个水壶倒水,直到装满或者倒空

题目分析

设现有水量为X,那么水量的变化只有增加或者减少x,增加减少y升水四中变化情况。
因此我们得到公示 mx+ny=z

1.设x和y最大公约数为a,z也一定是a的倍数
那么 x=k1倍的a,y=k2倍的a
mx+ny
=k1 * m * a+k2 * n * a
=(k1 * m + k2 * n) * a
=z
所以z一定也是a的倍数

2.那z是a的倍数就一定对吗
凭直觉是对的
具体物理证明方法如下:
⑴若b=0,则(a,b)=a.这时定理显然成立。
⑵若a,b不等于0.
记d = (a, b), 对ax + by = d,两边同时除以d,可得(a1)x + (b1)y = 1,其中(a1,b1) = 1。
转证(a1)x + (b1)y = 1。由带余除法:
① (a1) = (q1)(b1) + (r1), 其中0 < r1 < b1
② (b1) = (q2)(r1) + (r2), 其中0 < r2 < r1
③ (r1) = (q3)(r2) + (r3), 其中0 < r3 < r2

④ (rn-4) = (qn-2)(rn-3) + (rn-2)
⑤ (rn-3) = (qn-1)(rn-2) + (rn-1)
⑥ (rn-2) = (qn)(rn-1) + (rn)
⑦ (rn-1) = (qn+1)(rn) + 1
故,由⑦和⑥推出(rn-2)An-2 + (rn-1)Bn-1 = 1
再结合⑤推出(rn-3)An-3 + (rn-2)Bn-2 = 1
再结合④推出(rn-4)An-4 + (rn-3)Bn-3 = 1

再结合③推出(r1)A1 + (r2)B2 = 1
再结合②推出(b1)A0 + (r1)B0 = 1
再结合①推出(a1)x + (b1)y = 1
得证。

编写代码

  1. z要小于等于x+y,不然不成立
  2. 找出x,y最大公约数a
  3. r判断z是不是a的倍数
class Solution {
        public boolean canMeasureWater(int x, int y, int z) {
            if (x+y<z) {
                return false;
            }
            //注意x或y等于0的情况
            if (x==0||y==0) {
                return z==0||x+y==z;
            }
            return z%gcd(Math.max(x,y),Math.min(x,y))==0;
        }

        public int gcd(int biger,int smaller){
            if(biger%smaller==0)return smaller;
            return gcd(smaller,biger%smaller);
        }
}
上一篇:头条Android 岗年薪45W+面经分享(技术 6面,安卓开发kotlin推荐书籍


下一篇:齐博V系列如果发现被黑的排查方法附修复办法