题目描述:
- 描述: 求两个数的最大公约数
思路
- 求整数a、b的最大公约数,顾名思义,其实就是求同时满足a%c=0、b%c=0的最大正整数c,即求能够同时整除a和b的最大正整数c。
- 思路1:
- 若a、b均不为0,则依次遍历不大于a(或b)的所有正整数,依次试验它是否同时满足a%c=0 、b% c = 0两式,并在所有满足两式的正整数中挑选最大的那个即是所求;
- 若a、b其中有一个为0,那么最大公约数即为a、b中非零的那个;
- 若a、b均为0,则最大公约数不存在(任意数均可同时整除它们)。
评价:思路1该解法在大部分情况下要遍历不大于a(或b)的所有正整数,并依次测试它们是否满足条件,当a和b数值较大时(如10000000)该算法的时间复杂度较高,耗费的时间较多,往往不能在指定时间内得到结果- 思路2: 欧几里得算法
- 若整数g为a、b(不同时为0)的公约数,则g满足:
a=g*l,b=g*m(其中l、m为整数),同时a又可由b表示为:a=b*k+r(其中k为整数,r为a除以b后的余数) - 对如上三式做如下变形:
g*l=g*m*k+r==>r=g*(l-m*k) (g≠0) - 由上式可知,a、b的公约数g可以整除a除以b剩余的余数r(记为a mod b),即,a、b的公约数g同时也必是b、a mod b的公约数(因为满足既可以整除b又可以整除a mod b)
疑问:若g是a、b的最大公约数,它同样也是b、a mod b的最大公约数吗?- 假设g是a、b的最大公约数,但它并不是b、amodb的最大公约数,即存在g'>g且g'同时整除b与a mod b,这样必存在整数I'与m'使下式成立:
- 同时a、b、r之间满足下式:
- 如上式,g'同时也整除a与b,那么g'同时也是a、b的公约数
- 但b的最大公约数为g,而g'>g与假设不符,所以可证明a、b的最大公约数同时也是b、a mod b的最大公约数。
- 这样,我们把求a、b的最大公约数转换成了求b、amodb的最大公约数,那么问题不变而数据规模则明显变小,我们可以不断重复该过程,直到问题缩小成
求某个非零数与零的最大公约数,该非零数即是所求。
- 若整数g为a、b(不同时为0)的公约数,则g满足:
具体实现:
#include <iostream>
using namespace std;
/*
思路:(若 a、b 全为0则它们的最大公约数不存在,此处a、b不会同时为0)若 a、b 其中之一为0,则它们的最大公约数为 a、b 中非0的那个; a、b 都不为0,则使新 a = b,新 b = a % b ,然后重复该过程。
这就是欧几里得算法。
*/
int main(int argc, const char * argv[]) {
int dividend_1=0;
int dividend_2=0;
int temp=0; // 临时变量保存dividend1
while (cin>>dividend_1>>dividend_2) {
while (dividend_2>0) { // dividend_2不为0时一直更新
temp=dividend_1;
dividend_1=dividend_2;
dividend_2=temp%dividend_2;
}
cout<<dividend_1<<endl; // dividend_2为0时dividend_1即是所求
}
return 0;
}
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情”