mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
Create 365. Water and Jug Problem.md
This commit is contained in:
parent
668a5dad7f
commit
712358d68c
36
solutions/365. Water and Jug Problem.md
Normal file
36
solutions/365. Water and Jug Problem.md
Normal file
@ -0,0 +1,36 @@
|
||||
# [365. Water and Jug Problem](https://leetcode.com/problems/water-and-jug-problem/)
|
||||
|
||||
# 思路
|
||||
给定两个容量分别为 x 和 y 升但是没有刻度的量杯,问能不能量出z升水。
|
||||
|
||||
举个例子,若 x=4,y=3,z=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
|
||||
```
|
||||
有没有解。其中m,n为舀水和倒水的次数,正数表示往里舀水,负数表示往外倒水,那么上面的例子可以写成: 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);
|
||||
}
|
||||
};
|
||||
```
|
Loading…
Reference in New Issue
Block a user