两个数的最大公约数是指能同时被他们整除的最大正整数。
两个数的最大公约数等于它们中 较小的数 和 两数之差 的最大公约数。
252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5);
252 − 105 = 147,所以147和105的最大公约数也是21;
147 − 105 = 63,所以105和63的最大公约数也是21;
105 − 63 = 42,所以63和42的最大公约数也是21;
63 − 42 = 21,所以42和21的最大公约数也是21;
42 − 21 = 21,所以21和21的最大公约数也是21;
21 − 21 =0,最后剩下21和0,所以252和105的最大公约数是21。
更相减损法
#include <iostream>
#include<cmath>
using namespace std;
int main()
{
int a,b,t;
cin>>a>>b;
t=abs(a-b);
while(t!=0)
{
a=b;
b=t;
t=abs(a-b);
}
cout<<b<<endl;
return 0;
}
欧几里得(辗转相除法)
如果一个数是另一个数的几十倍甚至几千倍,一直做差非常麻烦(比如10000和10),这时求模运算,可以代替多次减数相同的差运算,直接得到最终需要的差值(如, 10000 % 10 =0)
非递归
#include <iostream>
using namespace std;
int main()
{
int a,b,t;
cin>>a>>b;
while(a%b !=0)
{
t=b;
b=a%b;
a=t;
}
cout<<b<<endl;
return 0;
}
递归
#include <iostream>
using namespace std;
int gcd(int a,int b)
{
if(a%b==0)
return b;
return gcd(b,a%b);
}
int main()
{
int a,b;
cin>>a>>b;
cout<<gcd(a,b)<<endl;
return 0;
}
穷举法(利用数学定义,也叫枚举法)
从两个数中较小数开始由大到小列举,直到找到公约数立即中断列举,得到的公约数便是最大公约数
找从0遍历到两者最小值,直到a,b均能被整除
#include <iostream>
#include<cmath>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
int t = a>b ? b : a;
while(t--)
{
if (a%t == 0 && b%t == 0)
break;
}
cout<<t<<endl;
return 0;
}
最小公倍数,就是a b的乘积除以它们两个的最大公约数,就是它们的最小公倍数。
计算运行时间
头文件 #include<ctime>
clock_t startTime = clock();
......
clock_t endTime = clock();
cout << "整个程序用时:" << double(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
如果程序运行时间连一毫秒都不要,那么最后显示的结果是 0s