LeetCode | 365. Water and Jug Problem 数学原理详细分析

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

猜你喜欢

转载自blog.csdn.net/u012737193/article/details/80347441
今日推荐