Leetcode 365. Water and Jug Problem

You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs.

If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end.

Operations allowed:

  • 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.

 

Example 1: (From the famous "Die Hard" example)

Input: x = 3, y = 5, z = 4
Output: True

Example 2:

Input: x = 2, y = 6, z = 5
Output: False

Credits:
Special thanks to @vinod23 for adding this problem and creating all test cases.

Next challenges: Strobogrammatic Number II Bulb SwitcherSort  Transformed Array

 

思路:命题1:如果a和b互质,则通过题目中的3种基本操作,我们可以实现[0, a+b]之间的任意一个容量。如果命题1正确,那么对于z=gc,x=ga,y=gb,且x+y>=z,我们有c属于[0, a+b],则z就是满足解。下面证明命题1的正确性。

证明:假设a<=b,如果填满a和b,那么就有总容量a+b。然后每次倒掉a直到不能倒为止,此时我们可以得到的容量c有

a + b,  b,  b - a,  b - 2a, ... , b % a 

最后我们将剩下的b%a倒入a,现在分别有b%a和b容量,总容量为b%a+b。然后我们每次倒掉a,直至不能倒为止,最后得到的容量是(b%a+b)%a=(b%a+b%a)=(2b)%a此时我们可以得到的容量c有

b + b % a,   b + b % a - a,  b + b % a - 2a, ... ,  (2b) % a 

重复以上操作a次,可以得到c:

 b + (2b) % a,  b + (2b) % a - a, b + (2b) % a - 2a, ..., (3b) % a
 :
 :
 :    
 b + ((a-1)b) % a,  b + ((a-1)b) % a - a,  b + ((a-1)b) % a - 2a, ... ,  (ab) % a

其中(ab)%a=0

命题2:集合 { b % a, (2b) % a, (3b) % a, ... , ((a-1)b) % a }{ 1, 2, 3, 4, 5, ... , a - 1 } 等价

假设命题2错误,则有m!=n都属于[1,a-1]并且(mb)%a==(nb)%a,则有((m-n)b)%a=0,则有(m-n)%a*b%a=0,则有(m-n)%a=0,则有m=n,与假设矛盾,所以命题2正确。因此上述a+1操作后形成的阵列的最后一列可以取到[0,a-1],倒数第2列可以取到[a,2a-1]....因此整个阵列可以取到[0,a+b]的值,所以命题1正确。

注意上述的阵列a和b同时扩大g倍,则整个阵列可以取到的值就是[0,g,2g,...,(a+b)g]。

那么对于z=gc,x=ga,y=gb,且x+y>=z,我们有c属于[0, a+b],则z就是满足解。

 

代码:

1 public class Solution {
2     public boolean canMeasureWater(int x, int y, int z) {
3         return z == 0 || z <= (long)x + y && z % GCD(x, y) == 0;
4     }
5     public int GCD(int x, int y) {
6         return x == 0 ? y : GCD(y%x, x);
7     }
8 }

 

posted @ 2017-07-18 19:17  Deribs4  阅读(214)  评论(0编辑  收藏  举报