Youare given two jugs with capacities x and y litres.There is an infinite amount of water supply available. You need to determinewhether it is possible to measure exactly z litresusing these two jugs.
If z litersof water is measurable, you must have z litersof water contained within oneor both buckets by the end.
Operationsallowed:
- Fill any of the jugs completely with water.
- Empty any of the jugs.
- Pour water from one jug into another till the other jug is completely full or the first jug itself is empty.
Example1: (From the famous "Die Hard" example)
Input: x = 3, y = 5, z = 4
Output: True
Example2:
Input: x = 2, y = 6, z = 5
Output: False
Credits:
Special thanks to @vinod23 for adding this problem and creating all test cases.
这一题给你三种操作,将一个杯子装满,将一个杯子倒空,或者是用一个杯子给另外一个杯子添水,直到其中一个杯子满或者是其中一个杯子空掉
其实这一题只要保证z是x和y最大公约数的倍数并且z <= x + y就行了,下面给出证明
根据贝祖公式,设c为x和y的最大公约数,则一定存在等式c = mx+ny,m和n为整数,并且mn < 0
当z = kc,则z = kmx + kny = m2*x + n2 * y
我们这里忽略x,y谁大谁小,公式可以写成:
z = m*x - n * y,这里m,n为非负整数 x可以大于y也可以小于y
1) 当x == y的时候,由于z <= x + y,两个杯子容量相等,z等于杯子容量的整数倍,一定可以得到
2) 当x > y的时候,我们执行以下操作,将x装满,然后用x向y中倒水,使得y变满,然后将y清空,继续以上操作直到x倒不满y,
这个时候将x中剩余的水倒入y,然后将x填满,继续以上操作,需要注意的是,只有将y装满才把y中的水倒掉
当最后一次将y倒掉之后,这个时候设x中剩余的水为t,这个时候z = t + p*x,当p为0的时候,这个时候z已经得到了,当p为1的时候,也能得到z,p不可能大于1
3) 当x < y的时候,我们执行以下操作,将x装满,然后用x向y中倒水,使得x变空,然后将x填满,继续以上操作直到x中的水比y中剩余容量多,
这个时候将用x将y装满,然后将y倒掉,然后将x中剩余的水倒入y,
继续以上操作,需要注意的是,只有将y装满才把y中的水倒掉
当最后一次将y倒掉之后,这个时候设x中剩余的水为t,这个时候z = t + p*x,当p为0的时候,这个时候z已经得到了,
当p不为0的时候,可以证明,对于任何z = t + p*x <= x + y这样的z都可以通过两个杯子的操作得到
因此证明了只要z为x和y最大公约数的倍数,并且z <= x+y,则z一定可以使用这两个杯子的一系列操作得到
这里还需要特别注意,题目中没有说明x,y,z的取值范围,这个时候应该把x,y,z当做可以取任何整数,包括0和负数
class Solution(object):
def canMeasureWater(self, x, y, z):
"""
:type x: int
:type y: int
:type z: int
:rtype: bool
"""
if z == 0: return True
if x == 0 and y == 0: return False
if z < 0 or z > x + y: return False
if x == 0 or y == 0: b = max(x, y)
else:
a = x
b = y
c = a % b
while c != 0:
a, b = (b, c)
c = a % b
if z % b == 0: return True
else: return False