搞懂gcd

gcd的概念

gcd是指最大公约数,如gcd(6, 4)就是指6和4的最大公约数,结果显然是2。

辗转相除法

辗转相除法:两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数,即 g c d ( a , b ) = g c d ( b , a % b ) ( a > b 且 a % b ≠ 0 ) gcd(a, b) = gcd(b, a \% b)\qquad (a > b且a \% b \neq 0) gcd(a,b)=gcd(b,a%b)(a>ba%b=0)

证明

不妨设 d = g c d ( a , b ) d = gcd(a, b) d=gcd(a,b)

那么一定存在正整数m和n使得 a = n d , b = m d a=nd, b=md a=nd,b=md

r = a % b , k = ⌊ a b ⌋ r=a\%b,k=\lfloor\frac{a}{b}\rfloor r=a%bk=ba

r = a − k b = ( n d ) − k ( m d ) = ( n − k m ) d r=a-kb=(nd)-k(md)=(n-km)d r=akb=(nd)k(md)=(nkm)d

显然r同样可被d整除,d同样是b和r的公约数

假设t是b和r的公约数,显然t也是a和b的公约数

即a和b的公约数,与b和 a % b a\%b a%b的公约数是相同的,那么它们的最大公约数肯定也是相同的

代码

int gcd(int x, int y){
   
	if(y == 0) return x;//倘若y为0了,说明上一次x和y是相等的且都等于最大公约数
    //上一次的y变成了这一次的x,那么我们直接返回x就好了
	return gcd(y, x % y);
}

你也可以用三元操作符?:来简化代码

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

c++中还有一个函数__gcd()可以直接用来求最大公因数

cout << __gcd(x, y) << endl;

裴蜀定理

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

裴蜀定理的证明

对于任意的整数x,y,ax+by都一定是d的倍数,这一点很容易证明。我们只证明后面的一定存在整数x,y,使ax+by=d成立
∵ d = g c d ( a , b ) ∴ d ∣ a , d ∣ b , ( 即 a 和 b 都 能 被 d 整 除 ) 设 s 为 a 和 b 的 线 性 组 合 的 最 小 正 值 , 不 妨 设 s = x a + y b 令 q = ⌊ a s ⌋ , r = a % s 则 r = a − q × ( x a + y b ) = ( 1 − q x ) a − ( q y ) b 显 然 r 同 样 是 a 和 b 的 线 性 组 合 , 且 0 ≤ r < s 但 我 们 已 经 假 设 了 是 s 是 a 和 b 的 线 性 组 合 的 最 小 正 值 ∴ r = 0 , 即 a % s = 0 ∴ s ∣ a , s ∣ b , ( 倘 若 不 理 解 为 什 么 s ∣ b 的 话 , 其 实 也 可 以 把 上 述 推 理 过 程 中 的 a 换 成 b ) 那 么 s 也 是 a 和 b 的 公 约 数 , 任 何 一 个 公 约 数 都 小 于

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值