有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?
如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。
你允许:
装满任意一个水壶
清空任意一个水壶
从一个水壶向另外一个水壶倒水,直到装满或者倒空
示例 1: (From the famous “Die Hard” example)
输入: x = 3, y = 5, z = 4
输出: True
示例 2:
输入: x = 2, y = 6, z = 5
输出: False
思路分析
这道题可以完全转化为裴蜀定理。
在数论中,裴蜀定理是一个关于最大公约数 (或最大公约式) 的定理。
裴蜀定理
对任意两个整数 a、b,设 d是它们的最大公约数。那么关于未知数 x和 y的线性丢番图方程(称为裴蜀等式):
ax+by=m
有整数解 (x,y) 当且仅当 m是 d的整数倍。裴蜀等式有解时必然有无穷多个解。
以题目给的例子x = 3, y = 5, z = 4,我们其实可以表示成3 3 - 1 5 = 4, 即3 x - 1 y = z。我们用 A 和 B分别表示3升的水壶和5升的水壶。那么我们可以:
倒满A(1)
将 A 倒到 B
再次倒满 A(2)
再次将 A 倒到 B(A这个时候还剩下1升)
倒空 B(-1)
将剩下的1升倒到 B
将 A 倒满(3)
将 A 倒到 B
 B 此时正好是4升
上面的过程就是3  x - 1  y = z的具体过程解释。
贝祖定理告诉我们,ax + by = z 有解当且仅当 z 是 x, y 的最大公约数的倍数。因此我们只需要找到 x, y 的最大公约数并判断 z 是否是它的倍数即可.

/*** @param {number} jug1Capacity* @param {number} jug2Capacity* @param {number} targetCapacity* @return {boolean}*/var canMeasureWater = function(jug1Capacity, jug2Capacity, targetCapacity) {const x = jug1Capacity, y = jug2Capacity, z = targetCapacityif (x + y < z) return false;if (z === 0) return true;if (x === 0) return y === z;if (y === 0) return x === z;function GCD(a, b) {let min = Math.min(a, b);while (min) {if (a % min === 0 && b % min === 0) return min;min--;}return 1;}return z % GCD(x, y) === 0;};
