——最大公约数就是两个自然数同时能被整除的最大的自然数数为两个数的最大公约数。或者说两个自然数共同的最大的约数。
先堆上无脑暴力
int gcd0(int a,int b){
int minn=min(a,b);
for(int i=minn;i>=1;i--){
if((a%i==0)&&(b%i==0)) return i;
}
}
进入算法
算法一、
这种忘了什么时候学的了,用到的性质是 gcd(a,b)=d*gcd(a/b,b/d) {d|a,d|b,|整除符号}。就像这样。
算法实现:
注:好像平时都不太用这个算法
int gcd1(int a,int b){
int ans=1,minn=min(a,b);
for(int i=2;i<=minn;i++){
if(!(a%i)&&!(b%i)){
ans=i*gcd1(a/i,b/i);
break;
}
}
return ans;
}
算法二、更相减损术
由:gcd(a,b)=gcd(a,a-b),a>b
证明:d=gcd(a,b) ,d|a,d|b,d|(a-b),完。
注:这种算法好像比较适用于高精度
int gcd(int a,int b){
while(a!=b){
if(a<b) b-=a;
else a-=b;
}
return a;
}
算法三、欧几里得算法
d=gcd(a,b)=gcd(b,a%b)
证明:如果a<b,证明显然成立。
如果b<a:
a=qb+r
r=a-qb , 又 d|a-q*b,故d|r
两边对b取模:a%b=r%b;
这是较常用的算法
int gcd3(int a,int b){
return a?b:gcd3(a%b,b);
}
究极算法
哈哈哈,就是库函数< algorithm >__gcd(a,b);
无脑调用。
总结
前几种算法都是一种思想,可以尝试着培养这种递归的思维,将复杂问题缩小,或者大规模数据缩小。
——end