力扣每日一刷Day 25
Practice Day twenty five:Leetcode T365
好了兄弟姐妹们,今天让我们学习一下肥鼠定理(贝祖定理/裴蜀定理)。今天就不给你们可视化了,这个还是比较简单。
贝祖定理(Bézout's Identity)是数论中一个非常重要的定理,它描述了两个整数的线性组合与它们的最大公约数之间的关系。
贝祖定理的表述:
对于任意两个整数
a
和b
(不同时为 0),存在整数x
和y
,使得:
ax+by=gcd(a,b)
其中:
gcd(a, b)
是a
和b
的最大公约数。x
和y
是满足等式的整数。
示例 :
设 a = 12
, b = 18
gcd(12, 18) = 6
- 找到整数
x
和y
使得:12x+18y=6
尝试解这个方程:
- 取
x = -1
,y = 1
,则:12×(−1)+18×1=−12+18=6
贝祖定理的含义:
贝祖定理告诉我们:
- 任何两个整数的线性组合(如
ax + by
)都一定是它们的最大公约数的倍数。 - 反过来,最大公约数
d = gcd(a, b)
也是所有形如ax + by
的最小正整数。
应用场景:
求解线性不定方程(如
如果ax + by = c
)c
是gcd(a, b)
的倍数,则有解。密码学(如 RSA 算法)
在模逆元计算中需要用到贝祖定理。数论问题
判断某个数是否能表示为两个数的线性组合。
好了,我们来拆解一下题目,看看他要搞什么飞机
题目条件:数字一、数字二、数字一和数字二之间可加减得到新数字、目标数字
题目目的:判断是否可以利用上述数字组合成目标数字
道理就是上面肥鼠定理的道理,我们直接上代码
class Solution {
public:bool canMeasureWater(int x, int y, int z) {if (x + y < z) {return false;}if (x == 0 || y == 0) {return z == 0 || x + y == z;}return z % gcd(x, y) == 0;}
};
九行代码结束战斗
1 第一个条件判断:
if (x + y < z) {return false;
}
- 如果两个水壶的总容量都小于
z
,那无论如何都无法得到z
升水,直接返回false
。
感到奇怪?认为一个水壶可以装多次水,可以多次叠加叠至所需容量的。但问题在于:你只有两个水壶,没有第三个容器。所以这个判断是成立的。
2 第二个条件判断:
if (x == 0 || y == 0) {return z == 0 || x + y == z;
}
- 如果其中一个水壶容量为
0
(比如x = 0
或y = 0
),那么只能通过另一个水壶来获得水。 - 此时:
- 如果
z == 0
,可以成功(不装水)。 - 如果
z == x + y
,也可以成功(将另一个水壶装满)。 - 否则不能。
- 如果
3 核心逻辑:
return z % gcd(x, y) == 0;
- 这是贝祖定理(Bézout's Identity)的应用。
- 它表示:如果
z
是x
和y
的线性组合(即存在整数a
和b
使得ax + by = z
),并且z <= x + y(这在前面的if已经验证过了)
,那么就可以实现。
关键点:
我是真的没有料到,但
gcd(x, y)
是 C++17 标准中引入的函数,用于计算两个整数的最大公约数(Greatest Common Divisor)。
- 只有当
z
是gcd(x, y)
的倍数时,才能被表示为x
和y
的线性组合。 - 所以,只要
z % gcd(x, y) == 0
,就说明可以完成目标。 - 这越过了倒水装水的过程,直达终点,流程被极致简化
今天到此结束,数学题真是又难又简单啊