重拾算法(三):求最大公约数的常用方法总结

来源:互联网 发布:有人招聘网络写手吗? 编辑:程序博客网 时间:2024/04/30 05:45

1.辗转相除法:


原理:

设两数为a、b(a>b),用gcd(a,b)表示a,b的最大公约数,r=a (mod b) 为a除以b的余数,k为a除以b的商,即a÷b=k.......r。辗转相除法即是要证明gcd(a,b)=gcd(b,r)。


第一步:令c=gcd(a,b),则设a=mc,b=nc


第二步:根据前提可知r =a-kb=mc-knc=(m-kn)c


第三步:根据第二步结果可知c也是r的因数


第四步:可以断定m-kn与n互质(假设m-kn=xd,n=yd (d>1),则m=kn+xd=kyd+xd=(ky+x)d,则a=mc=(ky+x)cd,b=nc=ycd,则a与b的一个公约数cd>c,故c非a与b的最大公约数,与前面结论矛盾),因此c也是b与r的最大公约数。


从而可知gcd(b,r)=c,继而gcd(a,b)=gcd(b,r)。


#include<stdio.h>int gcd(int a, int b){if (0 == a%b && b != 0){return b;}else{return gcd(b, a%b);}}int main(){int a, b;scanf("%d%d", &a, &b);if (a < b){int temp = a;a = b;b = temp;}int ans = gcd(a, b);printf("%d\n", ans);return 0;}


2.整数检测法:

原理:


找出两个数中最小的那个数n,然后从1到n遍历,找出最大公约数

#include<stdio.h>int main(){int a, b;scanf("%d%d", &a, &b);int ans = 0;if (a < b){int temp = a;a = b;b = temp;}for (int i = 1; i <= b; i++){if (a %i == 0 && b%i == 0){ans = i;}}printf("%d", ans);return 0;}


3.质因相乘法:

原理:


就是先把要求最大公约数的那几个数分别分解质因数,然后把这几个数公有的质因数相乘,所得的积就是要求的最大公约数。

例如:求12.18.54的最大公约数:

12 = 2 * 2 * 3;

18 = 2 * 3 * 3;

54 = 2 * 3 *3 *3;

所以最大公约数:

2 * 3 = 6;

具体的计算可以采用下列方法:(如图)



#include<stdio.h>bool isFlag(int num){bool flag = true;for (int i = 1; i <= num; i++){if (num %i == 0 && i != 1 && i != num){flag = false;break;}}return flag;}int main(){int a, b;scanf("%d%d", &a, &b);if (a < b){int temp = a;a = b;b = temp;}int numb = b;bool flag = true;int ans = 1;for (int i = 1; i <= numb; i++){if (isFlag(i)){if (a%i == 0){a = a / i;}else {flag = false;}if (b %i == 0){b = b / i;}else{flag = false;}if (flag == true){ans = ans *i;i = 1;}else{flag = true;}}}printf("%d", ans);return 0;}


1 0
原创粉丝点击