LC365-水壶问题,使用裴蜀定理及图解

以下是看了官方题解之后,根据自己的理解画出的示意图,若有理解错误还请大家指出。若没有理解错误,希望大家能通过此示意图理解裴蜀定理的解法。

题目

有两个容量分别为 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

问题

1、裴蜀定理的概念
2、对题目要求的理解
3、如何由此题联想到到裴蜀定理

解决

1、裴蜀定理,简单来说就是:

若x,y是整数,且gcd(x,y)=d,那么对于任意的整数a,b,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。

2、根据题目要求我们可以知道我们可以有如下操作:

  • 装满任意一个水壶:从外界装满
  • 清空任意一个水壶:向外界倒出
  • 从一个水壶向另外一个水壶倒水,直到装满或者倒空:
    所以可知每次操作之后总会有一个桶是满的或者空的,另外一个是空还是满还是非空都可以。

3、由2可知,每次的水的总量总是变化x或者y:这个变化可以理解为
(1)向外界倒出
(2)从外界倒入
注意:这里说的水的总量是两个桶内水的总量的变化总是x或者y。两个桶之间水的转移不算一次变化,因为水的总量没有变化,你只是换了个地方存水而已

那么我们只要找到x和y分别变化了几次能得到z就行了,即 a x + b y = z ax+by=z ax+by=z

其中a和b代表水的总量变化了a次或者b次,为负代表向外界倒了,为正代表从外界倒入,至于两个桶之间水的转移是不管的,因为无非就是从这个桶倒入另一个桶而已,两个桶内的总量没有变化。

根据这个等式可以想到裴蜀定理。为什么说可以想到呢?前提当然是你要知道这个定理的内容,就如同你要钉一个钉子,知道有锤子这个工具的存在,锤子很坚硬就适合钉钉子(比喻可能不太恰当)。裴蜀定理跟这个公式长得几乎一模一样,而且裴蜀定理求得的值都是x和y的最大公约数的倍数,那么题目给出了x和y,容易得到最大公约数,只要验证z是不是其倍数就能得出答案,至于a和b是几我们并不关心,因为根据裴蜀定理一定存在。

举个例子来实际感受一下

假设:
x = 3 , y = 5 , z = 4 x=3, y=5, z=4 x=3,y=5,z=4
根据裴蜀定理可知
( − 2 ) ∗ 3 + 2 ∗ 5 = 4 (-2)*3 + 2*5 = 4 (2)3+25=4
a = − 2 , b = 2 a=-2, b=2 a=2,b=2
代表:向外界倒出了2次3L的水,从外界向桶内倒入了2次5L的水,然后就得到了4L的水
如图:一定要注意,我们讨论的基本单位是水的总量变化
因为不会加自己切换的图片样式,只能加入gif了😫
水壶问题.gif

若还是不理解为什么讨论的水的总量变化,可以这样理解:上图的最后一步,两个桶剩下0L和4L的水,如果多此一举把4L的水倒入3L桶中,造成两个桶是3L和1L这样的状态,这样是没有意义的==因为水还是4L,水的总量没有变化,所以你爱咋放咋放,只要能够装下就行。所以我们讨论的水的总量的变化

//裴蜀定理
class Solution 
{
public:
    bool canMeasureWater(int x, int y, int z) 
    {
        if (x + y < z) return false;
        if (x == 0 || y == 0)
        {
            if (z == 0) return true;
            if (x + y == z) return true;
            return false;
        }
        return z % gcd(x, y) == 0;
    }
};

参考

LC官方题解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Mercurial

请我喝杯焦糖玛奇朵叭

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值