Skip to content

Latest commit

 

History

History
36 lines (29 loc) · 1.89 KB

365. Water and Jug Problem.md

File metadata and controls

36 lines (29 loc) · 1.89 KB

思路

给定两个容量分别为 x 和 y 升但是没有刻度的量杯,问能不能量出z升水。

举个例子,若 x=4,y=3,z=2,能不能行呢?我们先将4升杯装满,然后将其倒入3升杯子里面,还剩下1升,再将3升杯子清空将4升杯子剩下的1升水倒入3升杯子里, 然后再将4升杯子装满,再往3升杯子里倒入2升后3升杯子就满了,4升杯子剩下的就是2升水。

这题其实是个数学题(或者叫脑筋急转弯题?),参考讨论区, 假设我们有一个容量无限的大杯子,有两个容量分别为x和y的杯子,这题相当于问我们通过用两个小杯子往大杯子里倒水和往出舀水,问能不能使大杯子中的水刚好为z升。转换成数学就是问

z = m * x + n * y

有没有解。其中m,n为舀水和倒水的次数,正数表示往里舀水,负数表示往外倒水,那么上面的例子可以写成: 2 = 2 * 4 + (-2) * 3。

那上式在什么条件下有解呢?根据裴蜀定理,当且仅当 z 是 x 和 y 的最大公约数(greatest common divisor, gcd)的倍数时有解。

我们可以用辗转相除法算出最大公约数gcd(x, y),即

  • 如果y == 0gcd(x, 0) = x;
  • 否则,gcd(x, y) = gcd(y, x % y)

算出后,再判断z是不是其倍数即可,不过此题还有一个条件就是两个杯子的容量和不能小于z,即 x+y >= z

C++

class Solution {
private:
    int gcd(int x, int y){
        return y == 0 ? x: gcd(y, x % y);
    }
public:
    bool canMeasureWater(int x, int y, int z) {
        return (z == 0) || (x + y >= z && z % gcd(x, y) == 0);
    }
};