[题记-数学-最大公约数]水壶问题-leetcode
题目:水壶问题
有两个容量分别为 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
数学方法用到一个定理定理:贝祖定理
用简单的话说一下这个定理就是:
存在这么一个式子: ax + by = z,如果这个式子有解,那么z一定是x,y的最大公约数的倍数。
回来看我们的题目:
当然可以用搜索的方式去解,这里推荐用数学方法(来自官方解答)。
通过题目要求,我们可以认为每次操作只会让壶里的水增加x或y,减少x或y。
那么如果往没满的壶中加水或者排空呢?
- 根据题目要求不可能会出现两个桶有水并且都不满
- 对一个不满的水壶加满是没有意义的:如果另一个壶是空的,这个操作等于从初始状态加满这壶水;如果另一个壶是满的,这个操作等于从初始状态把两个壶都加满。
- 对一个不满的水壶清空也是没有意义的:如果另一个壶是空的,这个操作就等于回到初始状态;如果另一个壶是满的,这个操作等于从初始状态将另一个壶加满。
这样,我们就可以认为每次操作只会给水的总量带来x,y的变化,那么我们可以吧目标改为:
找到一对a,b使得:ax + by = z
如果 z <= x + y 我们的目标就可以达成
原因是:
- 若 a >= 0,b >= 0 显然可以达成目标
- 若 a < 0 可以进行以下操作:
- 给 y 壶倒水
- 把 y 壶的水倒入 x 壶中,如果 y 壶不为空,那就将 x 壶清空, y 壶继续往 x 壶倒水,重复以上步骤,直到 x 壶进行了 a 次清空,y 壶进行了 b 次倒水。
- 若 b < 0 同2。
由贝祖定理得出:ax + by = z,如果这个式子有解,那么z一定是x,y的最大公约数的倍数。
上代码(c):
bool canMeasureWater(int x, int y, int z){ if( x + y < z ) return false; if( x == 0|| y == 0 ) { if( z == 0 ) return true; else if( x + y == z ) return true; else return false; } //寻找最大公约数 while( y > 0 ){ int tmp = x; x = y; y = tmp%y; } if( z%x == 0 ) return true; else return false; }
2020-03-21-14:24:05

浙公网安备 33010602011771号