欧几里得算法: g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
适用场景:用于求最大公约数。
#include <stdio.h>
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int lcm(int a, int b)
{
return a / gcd(a, b) * b;
}
int main()
{
int a, b;
while (~scanf("%d%d", &a, &b))
{
printf("%d\n", gcd(a, b));
printf("%d\n", lcm(a, b));
}
}
备注:通过最大公约数(gcd)可求最小公倍数(lcm)
证明
求证 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b); – gcd 代表最大公约数
- 假设
a
>
b
,
t
=
g
c
d
(
a
,
b
)
;
a>b,t=gcd(a,b);
a>b,t=gcd(a,b);则存在p1,p2使下列等式成立:
{ a = t ∗ p 1 ; b = t ∗ p 2 ; = > g c d ( a , b ) = t = t ∗ g c d ( p 1 , p 2 ) \left\{ \begin{matrix} a=t*p1; \\ b=t*p2; \end{matrix} \right. =>gcd(a,b)=t=t*gcd(p1,p2) {a=t∗p1;b=t∗p2;=>gcd(a,b)=t=t∗gcd(p1,p2)
由上式得到 g c d ( p 1 , p 2 ) = 1 gcd(p1,p2)=1 gcd(p1,p2)=1,即p1和p2互素(互为质数) - 假设 a % b = r a\%b=r a%b=r,设 a = k ∗ b + r a=k*b+r a=k∗b+r
- 将1代入2得:
t
∗
p
1
=
k
∗
t
∗
p
2
+
r
,
所
以
r
=
(
p
1
−
k
∗
p
2
)
∗
t
t*p1=k*t*p2+r,所以r=(p1-k*p2)*t
t∗p1=k∗t∗p2+r,所以r=(p1−k∗p2)∗t,整理得:
{ b = p 2 ∗ t ; a % b = r = ( p 1 − k ∗ p 2 ) ∗ t ; \left\{ \begin{matrix} b=p2*t ;\\ a\%b=r=(p1-k*p2)*t; \end{matrix} \right. {b=p2∗t;a%b=r=(p1−k∗p2)∗t; - 设
g
c
d
(
p
2
,
p
1
−
k
∗
p
2
)
=
m
gcd(p2,p1-k*p2)=m
gcd(p2,p1−k∗p2)=m,则:
{ p 2 = m ∗ n 1 ; p 1 − k ∗ p 2 = m ∗ n 2 ; \left\{ \begin{matrix} p2=m*n1 ;\\ p1-k*p2=m*n2; \end{matrix} \right. {p2=m∗n1;p1−k∗p2=m∗n2;
化简得:
{ p 2 = m ∗ n 1 ; p 1 = m ∗ ( n 2 + k ∗ n 1 ) \left\{ \begin{matrix} p2=m*n1 ;\\ p1=m*(n2+k*n1) \end{matrix} \right. {p2=m∗n1;p1=m∗(n2+k∗n1) - 因为步骤1得到了 g c d ( p 1 , p 2 ) = 1 gcd(p1,p2)=1 gcd(p1,p2)=1,结合步骤4知,m=1;即 g c d ( p 2 , p 1 − k ∗ p 2 ) = 1 gcd(p2,p1−k∗p2)=1 gcd(p2,p1−k∗p2)=1;代入3即可得: g c d ( b , a % b ) = t gcd(b,a\%b)=t gcd(b,a%b)=t。所以: g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)