LeetCode/solutions/365. Water and Jug Problem.md

37 lines
1.9 KiB
Markdown
Raw Normal View History

2019-12-13 03:23:32 +00:00
# [365. Water and Jug Problem](https://leetcode.com/problems/water-and-jug-problem/)
# 思路
给定两个容量分别为 x 和 y 升但是没有刻度的量杯问能不能量出z升水。
举个例子,若 x=4y=3z=2能不能行呢我们先将4升杯装满然后将其倒入3升杯子里面还剩下1升再将3升杯子清空将4升杯子剩下的1升水倒入3升杯子里
然后再将4升杯子装满再往3升杯子里倒入2升后3升杯子就满了4升杯子剩下的就是2升水。
这题其实是个数学题(或者叫脑筋急转弯题?),参考[讨论区](https://leetcode.com/problems/water-and-jug-problem/discuss/83720/Clear-Explanation-of-Why-Using-GCD)
假设我们有一个容量无限的大杯子有两个容量分别为x和y的杯子这题相当于问我们通过用两个小杯子往大杯子里倒水和往出舀水问能不能使大杯子中的水刚好为z升。转换成数学就是问
```
z = m * x + n * y
```
有没有解。其中mn为舀水和倒水的次数正数表示往里舀水负数表示往外倒水那么上面的例子可以写成: 2 = 2 * 4 + (-2) * 3。
那上式在什么条件下有解呢?根据[裴蜀定理](https://zh.wikipedia.org/wiki/%E8%B2%9D%E7%A5%96%E7%AD%89%E5%BC%8F),当且仅当 z 是 x 和 y 的最大公约数greatest common divisor, gcd的倍数时有解。
我们可以用辗转相除法算出最大公约数`gcd(x, y)`,即
* 如果`y == 0``gcd(x, 0) = x`;
* 否则,`gcd(x, y)` = `gcd(y, x % y)`
算出后再判断z是不是其倍数即可不过此题还有一个条件就是两个杯子的容量和不能小于z`x+y >= z`
# C++
``` 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);
}
};
```