约数相关算法

1. 最大公约数

a a a b b b 的最大公约数用 g c d ( a , b ) gcd(a,b) gcd(a,b) 表示

最大公约数基本上有这几种算法,分别是:

  1. 暴力,复杂度 O ( m i n ( a , b ) ) O(min(a,b)) O(min(a,b))
  2. 利用 九章算法 · 更相减损术 g c d ( a , b ) = g c d ( a − b , b ) gcd(a,b)=gcd(a-b,b) gcd(a,b)=gcd(ab,b) ,不断缩小数据,边界条件是 g c d ( a , 0 ) = a   g c d ( 0 , b ) = b gcd(a,0)=a\ gcd(0,b)=b gcd(a,0)=a gcd(0,b)=b
  3. 利用欧几里得发现的 g c d ( a , b ) = g c d ( b , a m o d    b ) gcd(a,b)=gcd(b,a \mod b) gcd(a,b)=gcd(b,amodb) 边界条件也是一样

因为第三种数据缩小的最快,所以使用第三个,其利用第二个多来几次就可以,这里给另一种证明:

a < b a \lt b a<b a m o d    b = a a \mod b=a amodb=a ,所以 g c d ( a , b ) = g c d ( b , a ) = g c d ( b , a m o d    b ) gcd(a,b)=gcd(b,a)=gcd(b,a \mod b) gcd(a,b)=gcd(b,a)=gcd(b,amodb)

a ≥ b a \ge b ab ,设 a = q b + r a=qb+r a=qb+r ,其中 0 ≤ r < b 0 \le r \lt b 0r<b (其实就是 a / b a/b a/b 的商和余数),设 g = g c d ( a , b ) g=gcd(a,b) g=gcd(a,b)

r = a m o d    b r=a \mod b r=amodb

∵ g ∣ a ,   g ∣ b \because g \mid a,\ g \mid b ga, gb

∴ g ∣ q b + r ,   g ∣ q b \therefore g \mid qb+r,\ g \mid qb gqb+r, gqb

∴ g ∣ r \therefore g \mid r gr

∴ g ∣ a m o d    b \therefore g \mid a \mod b gamodb

∵ a m o d    b < b \because a \mod b \lt b amodb<b

∴ g = g c d ( b , a m o d    b ) \therefore g=gcd(b,a \mod b) g=gcd(b,amodb)

于是我们可以这样求最大公约数;

int gcd(int a, int b)
{
   
	if(b==0)return a;
	return gcd(b, a%b);
}

我们也可以用循环实现:

int gcd(int a, int b)
{
   
	if(a<b)swap(a, b);
	while(b)
	{
   
		a%=b;
		swap(a, b);
	}
	return a;
}

这是最常用的方法,当然还有一个针对高精度数据的方法

二进制算法

对于两个数 a , b a,b a,b ,当 a = b a=b a=b 时 , gcd ⁡ ( a , b ) = a \gcd(a,b)=a gcd(a,b)=a

否则,当 a , b a,b a,b 都是偶数时 , gcd ⁡ ( a , b ) = 2 × gcd ⁡ ( a 2 , b 2 ) \gcd(a,b)=2 \times \gcd(\frac{a}{2},\frac{b}{2}) gcd(a,b)=2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值