根据教师课件,写成本文。未经允许,禁止转载。
gcd,即最大公约数,指的是几个整数中公有的约数中最大的一个。
已知 a,b,求 gcd(a,b)。
方法一:枚举法#
从 min(a,b) 到 1 枚举,找到第一个 x 符合题意,就退出循环。
时间复杂度 O(min(a,b))。
方法二:分解质因数#
令 a=px11px22…pxnn,b=py11py22…pynn,其中xi,yi≥0 且不同时为 0。
则 gcd(a,b)=pmin(x1,y1)1pmin(x2,y2)2…pmin(x3,y3)3。
时间复杂度 O(√min(a,b))。
void Gcd()
{
for(int x=2;x*x<=min(a,b);x++)
{
while (a % x==0 && b % x==0) {a/=x;b/=x;ans*=x;}
while (a % x==0)a/=x;
while (b % x==0)b/=x;
}
if (a % b==0)ans*=b;
else if (b % a==0)ans*=a;
printf("%d",ans);
}
方法三:辗转相除(欧几里得算法)#
定理:gcd(a,b)=gcd(b,a%b)。
证明:
设 gcd(a,b)=p,则有 a=a′∗p,b=b′∗p,gcd(a′,b′)=1。
a%b=a−⌊ab⌋∗b=a′∗p−⌊ab⌋∗b′∗p=p∗(a′−⌊ab⌋∗b′)。
gcd(b,a%b)=gcd(b′∗p,p∗(a′−⌊ab⌋∗b′))=p∗gcd(b′,a′−⌊ab⌋∗b′)。
现证明 gcd(b′,a′−⌊ab⌋∗b′)=1,使用反证法。假设 gcd(b′,a′−⌊ab⌋∗b′)=t(t>1)。
b′=b′′∗t,a′−⌊ab⌋∗b′=c′∗t。
a′=c′∗t+⌊ab⌋∗b′=c′∗t+⌊ab⌋∗b′′∗t=t∗(c′+⌊ab⌋∗b′′)。
则 gcd(a′,b′)≥p,与 gcd(a′,b′)=1 矛盾,因此 gcd(b′,a′−⌊ab⌋∗b′)=1。
gcd(b,a%b)=p=gcd(a,b)。
时间复杂度 O(log(max(a,b)))。
分析:
-
设 a>b。
若 a>2b,则 b≤a2,规模减小一半。反之 a<2b,则 a%b<a2。
因此时间复杂度是 log 级别。
-
斐波那契分析:传送门。
int Gcd(int a,int b)
{
if (b==0) return a;
else return Gcd(b,a % b);
}
方法四:二进制法#
当 a<b 时, gcd(a,b)=gcd(b,a)。
当 a=b 时 gcd(a,b)=a。
当 a,b 同为偶数时,gcd(a,b)=2∗gcd(a2,b2)。
当 a 为偶数,b 为奇数时,gcd(a,b)=gcd(a2,b)。
当 a 为奇数,b 为偶数时,gcd(a,b)=gcd(a,b2)。
当 a,b 为奇数时,gcd(a,b)=gcd(a−b,b)。
注:此法适合高精度求最大公约数。
int Gcd(int m,int n)
{
if (m==n) return m;
if (m<n) return Gcd(n,m);
if (m & 1==0) return (n & 1==0)? 2*Gcd(m/2,n/2):Gcd(m/2,n);
return (n & 1==0)? Gcd(m,n/2): Gcd(n,m-n);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】