1. 程式人生 > >leetcode 365. Water and Jug Problem 兩個水杯倒水問題 + 最大公約數Gcd輾轉相除法

leetcode 365. Water and Jug Problem 兩個水杯倒水問題 + 最大公約數Gcd輾轉相除法

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

這道題可以轉化為最經典的問題,兩個杯子倒水可以倒出指定體積的水的問題,可以通過輾轉相除法來完成,網上看到了這個問題才想到。

程式碼如下:


/*
 * 這道問題其實可以轉換為有一個很大的容器,我們有兩個杯子,容量分別為x和y,
 * 問我們通過用兩個杯子往裡倒水,和往出舀水,問能不能使容器中的水剛好為z升。
 * 那麼我們可以用一個公式來表達:
 * z = m * x + n * y
 * 其中m,n為舀水和倒水的次數,正數表示往裡舀水,負數表示往外倒水,
 * 那麼題目中的例子可以寫成: 4 = (-2) * 3 + 2 * 5,即3升的水罐往外倒了兩次水,
 * 5升水罐往裡舀了兩次水。那麼問題就變成了對於任意給定的x,y,z,存不存在m和n使得上面的等式成立。
 * 根據裴蜀定理,ax + by = d的解為 d = gcd(x, y),那麼我們只要只要z % d == 0,上面的等式就有解,
 * 所以問題就迎刃而解了,我們只要看z是不是x和y的最大公約數的倍數就行了,
 * 別忘了還有個限制條件x + y >= z,因為x和y不可能稱出比它們之和還多的水
 * */
class Solution { public boolean canMeasureWater(int x, int y, int z) { return z == 0 || (z <= x + y && z % gcd(x, y) == 0); } int gcd(int x, int y) { return y==0?x:gcd(y, x%y); } }

下面是C++的做法,就是一個輾轉相除法

程式碼如下:

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>

using namespace std;



class Solution 
{
public:
    bool canMeasureWater(int x, int y, int z)
    {
        return z == 0 || x + y >=  z && z%gcd(x, y) == 0;
    }

    int gcd(int x, int y)
    {
        return y == 0 ? x : gcd(y, x%y);
    }
};