【广告】
此篇是本人第一篇博客,请大家多多鼓励
【最大公因数】
最大公因数(简称GCD),是指两个及以上整数共有的最大的正整数因数
例如,18和24的最大公因数是6;20和50最大公因数是10
在数学上,两个数的最大公因数简写为(两个数设为a,b):(a,b)
【两种特殊情况】
两种特殊情况:
1、两数为倍数关系,GCD为较小那个数
2、两数互质,GCD=1
怎么用C++求最大公因数?
办法当然有……
【数学:短除法】
小学时,最常用的短除法
第一种C++求最大公因数写法,如下:
【穷举法】:
int gcd(int a,int b){
for(int i=a;i>=0;i--){
if(a%i==0&&b%i==0){
return i;
}
}
}
显然,如果你将这种写法在竞赛上使用,那就是超时的料
因为这个时间复杂度达到了O(a),如果a大于100000000,那么肯定超过1s
那么怎么办呢?
没关系,还有第二种解法
用质因数分解法
一样是穷举法
但是代码太长,就不展示了(#^.^#)
【更相减损法/辗转相减法】
想知道第三种,必须知道两个定理:
定理1:如果(a-b)%x = 0 一定有 a%x==b%x;反之亦然。
定理2:如果a>b,则GCD(a,b)=GCD(a-b,b)。
例如: GCD(21,14) = GCD(7,14) = GCD(14,7) = GCD(7,7) = 7
所以由定理2得到第三种解法
也称更相减损法/辗转相减法
int gcd(int a,int b){
while(a!=b){
if(a<b){
swap(a,b);
a-=b;
}
}
return a;
}
还没结束!!!
【辗转相除法】
还有第四种写法
定理3:如果b>0,有GCD(a,b)=GCD(b,a%b)。
证明:多次使用定理2:
GCD(a,b)=GCD(a-b,b)= GCD(a-b-b,b)=...=GCD(a%b,b)=GCD(b,a%b)。
例如:GCD(377,319) = GCD(319,58) = GCD(58, 29) = GCD(29,0)=29
由定理3可以得到著名的辗转相除法(也叫欧几里德算法)
代码如下
int gcd(int a,int b){
while(b){
int temp=b;
b=a%b;
a=temp;
}
return a;
}
还有递归写法
int gcd(int a,int b){
if(b==0){
return a;
}
return gcd(b,a%b);
}
辗转相除法是非常简明高效的算法,体现了程序设计中的数学之美。