最大公约数

辗转相除法、更相减损术(九章算术) 还是有点迷糊,

穿精又带淫゛_ 提交于 2020-04-07 07:27:12
首先重点无论式辗转相除法还是更相减损术,最重要的原理是:两个整数的最大公约数等于其中较小的数和两数的差的最大公约数 你可以这么理解, C=(A,B) ,C为A,B的最大公约数;即A,B都有公因数C,那么A-B也有公因数C, A%C=0; B%C=0; A%C-B%C=(A-B)%C=0 假设有两个数x和y,存在一个最大公约数z=(x,y),即x和y都有公因数z, 那么x一定能被z整除,y也一定能被z整除,所以x和y的线性组合mx±ny也一定能被z整除。(m和n可取任意整数) 对于辗转相除法来说,思路就是:若x>y,设x/y=n余c,则x能表示成x=ny+c的形式,将ny移到左边就是x-ny=c,由于一般形式的mx±ny能被z整除,所以等号左边的x-ny(作为mx±ny的一个特例)就能被z整除,即x除y的余数c也能被z整除。一直下操作, 最后就是更相减损术是拿来相减,而辗转相除是取余;当两个数很接近的时候前者算法效率高,两个数差距很大的时候后者效率高! 来源: https://www.cnblogs.com/Left-Behind/p/7554000.html

更相减损法和辗转相除法(GCD)求最小公倍数和最大公约数

佐手、 提交于 2020-04-07 07:26:14
更相减损法和辗转相除法(GCD)求最小公倍数和最大公约数 标签(空格分隔): 算法 算法竞赛 这两种算法平时经常听到,听起来也很装逼,但是我老是忘了他们的原理,今天好好想想,写下来。 更相减损法 更相减损法最早起源于我国的《九章算术》,用于求两个数的最小公倍数。大意是给定两个数a,b,如果存在偶数,就将偶数以2;否则,就比较两数大小,用大数减小数,得到一个差;对差和剩下的那个小数重复该过程,直到两数相等,下一次相减结果为0,这时的数就是a和b的最大公约数。注意,去掉偶数除以2的步骤,也正确,但是加上这一步可能会让时间复杂度减少。 例如:15和12。15-12=3;12-3=9;9-3=6;6-3=3;3=3,跳出。则最大公因数是3。 算法的C/C++代码写法如下(循环实现): int gcdgxjs(int a,int b) { while (a!=b) { if (a if (a>b) a-=b; else b-=a; } return a; ) 辗转相除法 辗转相除法最早是由欧几里得发现的,也被用来求最大公约数。算法是这样的:给定两个数a,b,求a%b,如果余数非0,就继续用除数除以余数,重复该过程,直到除数为0。此时的被除数,就是最大公约数。 例如,42和12。42%12=6;12%6=0,6&0,此时的6即为最大公约数。 算法的C/C++代码写法如下(递归实现): int

求两个数的最大公约数,辗转相除法与更相减损法(递归迭代)

▼魔方 西西 提交于 2020-04-07 07:26:06
问题:给出两个数a和b,求出他们的最大公约数(greatest common divisor)。 解法一:辗转相除法,又叫欧几里得算法。两个正整数a和b(a>b),他们的最大公约数等于a除以b的余数和b之间的最大公约数。 比如10和25,25除以10余5,那么10和25的最大公约数等同于5和10之间的最大公约数。 //辗转相除法 递归解法 int gcd(int a,int b){ if(a%b==0) return b; return (b,a%b); } //辗转相除法 迭代解法int gcd2(int a,int b){ int t; while(b!=0){ t=b; b=a%b; a=t; } return a; } 解法二:更相减损术,出自中国古代的《九章算术》。两个正整数a和b(a>b),他们的最大公约数等于a-b的差值c和较小数b的最大公约数。 比如10和25,25-10=15,那么10和25的最大公约数等于10和15的最大公约数。 //更相减损术 递归 int gcd3(int a,int b){ if(a==b) return a; if(a>b) return gcd(a-b,b); else return gcd(b-a,a); } //更相减损术 迭代 int gcd4(int a,int b){ while(a*b!=0){ if(a>b) a=a-b;

字符串的最大公约数

余生长醉 提交于 2020-04-06 20:48:20
此博客链接: 题目链接: 题解: 方法: 思路: 心酸历程: 1.一开始想着遍历短的字符串长度,只要两个字符串的每个字符相等就重新加入str中,但是运行时ABABAB和ABAB的最大公约数是AB不是ABAB。 2.想到了利用求最大公约数,遍历到最大公约数长度,比较两个字符串的字符,但是这样少考虑的两个字符串只有最大公约数前面字母相等的情况。例如ABCDEF和ABCD。 3. 来源: https://www.cnblogs.com/ping2yingshi/p/12644155.html

最大公约数和最小公倍数

南笙酒味 提交于 2020-03-23 13:04:11
求任意两个正整数的最大公约数和(GCD)和最小公倍数(LCM) *问题分析与算法设计 手工方式求两个正整数的蝚大公约数的方法是用辗转相除法,在程序中可以模拟这种方式。 *程序说明与注释 #include<stdio.h> int main() { int a,b,num1,num2,temp; printf("Input a & b:"); scanf("%d%d",&num1,&num2); if(num1>num2) /*找出两个数中的较大值*/ { temp=num1; num1=num2; num2=temp; /*交换两个整数*/ } a=num1; b=num2; while(b!=0) /*采用辗转相除法求最大公约数*/ { temp=a%b; a=b; b=temp; } printf("The GCD of %d and %d is: %d\n",num1,num2,a); /*输出最大公约数*/ printf("The LCM of them is: %d\n",num1*num2/a); /*输出最小公倍数*/ } *运行结果 1.Input a & b: 20 55 The GCD of 20 and 55 is: 5 The LCM of them is: 220 2.Input a & b: 17 71 The GCD of 17 and 71 is:

辗转相除法的证明

只愿长相守 提交于 2020-03-22 22:43:36
辗转相除法的证明   设两数为a、b(b<a),求它们最大公约数的步骤如下:用b除a,得a=bq+r(0≤r<b)(q是这个除法的商)。若r=0,则b是a和b的最大公约数。若r≠0,则继续考虑。   首先,应该明白的一点是任何 a 和 b 的公约数都是 r 的公约数。要想证明这一点,就要考虑把 r 写成 r=a-bq。现在,如果 a 和 b 有一个公约数 d,而且设 a=sd , b=td, 那么 r = sd-tdq = (s-tq)d。因为这个式子中,所有的数(包括 s-tq )都为整数,所以 r 可以被 d 整除。   对于所有的 d 的值,这都是正确的;所以 a 和 b 的最大公约数也是 b 和 r 的最大公约数。因此我们可以继续对 b 和 r 进行上述取余的运算。这个过程在有限的重复后,可以最终得到 r=0 的结果,我们也就得到了 a 和 b 的最大公约数。 来源: https://www.cnblogs.com/oiercc/p/7294315.html

欧几里德算法(辗转相除)证明

狂风中的少年 提交于 2020-03-16 02:07:27
过了这么久,终于知道了辗转相处的证明了,以前只是记住了,但不是真的很理解,现在写一下它的证明,以便下次忘了的时候看一下。辗转相除是求两个数的最大公约数的。 要证这个定理成立,只需要证明 gcd(a, b) = gcd(b, a % b) 就行了 证明:令a % b = r, 所以a = k * b + r, 所以r = a - k * b,假设d为a,b的一个公约数,那么 d|a, d|b,(d|a的意思就是d整除a,也就是a能被d整除),所以a - k * b 也一定能被d整除,即 d|r, 也就是 d|(a % b), 因此d也是b 和 (a % b)的公约数,因此a,b 的公约数和b, (a%b)的公约数也是一样的,其最大公约数也一定相同,所以gcd(a, b) = gcd(b, a % b); 所以有了这个等式之后,基本上就算完了,还有一步就是怎么到最后求个具体的数,当b等于0时候就可以了,因为最后递归好多还是和原来的那个公寓数是相同的,最后有0了,他俩的最大公约数就是他本身了,也就是a了,用递归代码如下 1 int gcd(int a, int b) 2 { 3 return (b == 0 ? a : gcd(b, a % b)); 4 } 来源: https://www.cnblogs.com/Howe-Young/p/4329362.html

最大公约数和最小公倍数

别来无恙 提交于 2020-03-14 16:02:53
输入两个正整数m和n,求最大公约数和最小公倍数 最大公约数: 两个或多个整数共有约数中最大的一个,求最大公约数:质因数分解法、短除法、辗转相除法、更相减损法 最小公倍数: 两个或多个整数公有的倍数叫做它们的公倍数,其中最小的数是最小公倍数,求最小公倍数: 质因数分解法、公式法 辗转相除法求最大公约数: 辗转相除法, 又名欧几里德算法,是求最大公约数的一种方法。它的具体做法是:用较小数除较大数, 再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的 最大公约数,那么最后的除数就是这两个数的最大公约数 公式法求最小公倍数: 两个数的乘积等于这两个数的最大公约数与最小公倍数的积 //这里采用 辗转相除法求最大公约数 公式法求最小公倍数 代码如下: 1 #include <stdio.h> 2 3 //求最大公约数: 4 int gcd(int x , int y) 5 { 6 if(!y) 7 return x; 8 else 9 return gcd(y , x%y); 10 } 11 12 //求最小公倍数: 13 int lcm(int a, int b) 14 { 15 return a*b/gcd(a,b); 16 } 17 18 int main() 19 { 20 int a, b; 21 scanf(

浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用

与世无争的帅哥 提交于 2020-03-12 08:59:08
一、欧几里得算法及其证明 1.定义: 欧几里得算法又称辗转相除法,用于求两数的最大公约数,计算公式为GCD(a,b)=GCD(b,a%b); 2.证明: 设x为两整数a,b(a>=b)的最大公约数,那么x|a,x|b; ①由整数除法具有传递性(若x能整除a,x能整除b,那么x可整除a,b的任意线性组合)知x|a-b; ②设x不是b的因子,则x不是b和a-b的公因子;设x不是a的因子,则x不是b和a-b的公因子;所以可以得出GCD(a,b)=GCD(b,a-b); ③由a>=b知,a可表示为a=b*q+r;则a减去q个b剩下的数字即为r,所以GCD(a,b)=GCD(b,a%b); 3.一般代码: (1)递归形式: int gcd(int a,int b){return b?gcd(b,a%b):a;} (2)迭代形式: int gcd(int a,int b){ for(;;) { if(b==0)return a; int temp=a%b; a=b; b=temp; } } 4.几个性质: (1)若GCD(a,b)=1,那么a,b两数互质。 (2)GCD(a,2a)=a; (3)GCD(a,0)=a; (4)GCD(a,b)=GCD(-a,b)=GCD(a,-b)=GCD(-a,-b); (5)LCM(a,b) GCD(a,b)=a b(LCM为两数小公倍数); (6)GCD