众所周知,求最大公约数一般辗转相除,代码很短,主要在于证明
int gcd(int x,int y)
{
if(y==0) return x;
else return gcd(y,x%y);
}
也可以写为
int gcd(int a,int b)
{
return b ? gcd(b,a%b) : a;
}
时间复杂度是 O ( l o g ( a + b ) ) O(log(a+b)) O(log(a+b)),比试除法划算多了。
代码很短,主要看证明。
一开始我想的是设
x
x
x和
y
y
y的最大公约数为
a
a
a
则
x
=
m
×
a
x=m \times a
x=m×a,
y
=
n
×
a
y=n \times a
y=n×a,(这里先保证
x
>
y
x>y
x>y)
m
m
m和
n
n
n为互质数
所以
x
−
y
=
(
m
−
n
)
×
a
x-y=(m-n) \times a
x−y=(m−n)×a
此时
x
−
y
x-y
x−y与
x
x
x的最大公约数还是
a
a
a
但是这里就忽略了一个问题:
我不会证明当
m
m
m和
n
n
n为互质数的时候
(
m
−
n
)
(m-n)
(m−n)与
m
m
m和
n
n
n中的任意一个数也是互质数!
所以此方法不够严谨。
当这个博客发出去第一次后,我突发奇想可以加上反证法:
已知
m
m
m和
n
n
n为互质数,若
(
m
−
n
)
(m-n)
(m−n)和
m
m
m不为互质数
则有
(
m
−
n
)
=
q
×
t
(m-n)=q \times t
(m−n)=q×t,
m
=
p
×
t
m=p \times t
m=p×t,(
t
t
t为大于
1
1
1的整数)
那么
n
=
(
m
−
(
m
−
n
)
)
=
(
p
−
q
)
×
t
n=(m-(m-n))=(p-q) \times t
n=(m−(m−n))=(p−q)×t
这样的话
n
n
n和
m
m
m就不是互质数了
所以假设不成立
这样的话
g
c
d
(
x
,
y
)
gcd(x,y)
gcd(x,y)就等于
g
c
d
(
y
,
x
−
y
)
gcd(y,x-y)
gcd(y,x−y)
而
m
o
d
mod
mod就相当于是减去了
a
a%b
a就相当于
a
a
a减去了
k
k
k个
b
b
b
这样就省去了很多减的运算
辗转相除到最后,其中一个数为
0
0
0时
另一个数即为原来两数的最大公因数
由定义“ ∀ x , y ∈ N \forall x,y\in \N ∀x,y∈N, g c d ( a , b ) × l c m ( a , b ) = a × b gcd(a,b) \times lcm(a,b)=a \times b gcd(a,b)×lcm(a,b)=a×b”可得
int lcm(int x,int y)
{
return (a*b/gcd(a,b));
}
例题:
∙
\bullet
∙ [NOIP2001 普及组]最大公约数和最小公倍数问题
∙
\bullet
∙ CF1152C Neko does Maths