辗转相除求最大公约数

求最大公约数的最常用的算法是欧几里得算法,也称为辗转相除法。问题定义为求i和j的最大公约数gcd(i,j),其中i和j是整数,不妨设i>j。
算法可以递归的表示:
1. 如果j能整除i,那么gcd(i,j)=j;

2. j不能整除i,令r=i%j,那么gcd(i,j)=gcd(j,r)。

C实现

int gcd(int i, int j)
{
    int r = i % j;
    return r == 0 ? j : gcd(j, r);
}

分析

算法的步骤1,显然成立(最大公约数定义);

要证明步骤2:

设d是i和j的最大公约数,
那么i=md,j=nd,m和n互质(否则d不是最大公约数)。
由r=i%j可以得到i=kj+r,k=⌊m/n⌋,k≥1(我们前面假设过i>j)。
把i=md,j=nd代入得到
md=knd+r
那么
r=(m-kn)d
m-kn和m也是互质的。
所以得到d是j和r的最大公约数。

时间复杂度分析:
逆着看该算法,最后的余数是0,倒数第二次余数是d,倒数第三次是kd,k>1…
由于组成了一个数列,{0,d,kd,nkd+d,…}
数列的n项加上n+1项,比n+2项要小,所以比斐波纳契数列增长的要快。
我们已知斐波纳契数列增长速度是指数,那么待分析的数列也是指数增长。
设欧几里得算法需要k次,那么j=O(2^k),则k=O(lg j)。

所以欧几里得算法求最大公约数的时间复杂度是对数量级的,速度非常快。

时间: 2024-10-25 22:28:43

辗转相除求最大公约数的相关文章

辗转相除 求最大公约数!or 最小公倍数

求最大公约数和最小公倍数的经典算法--辗转相除法描述如下: 若要求a,b两数的最大公约数和最小公倍数,令a为a.b中较大数,b为较小数,算法进一步流程: while(b不为0) { temp=a%b: a=b: b=temp } 最后a即为两数的最大公约数,最大公倍数为: a*b/最大公约数 c语言代码: 01.int divisor (int a,int b) /*自定义函数求两数的最大公约数*/ 02.{ 03. int temp; /*定义整型变量*/ 04. if(a<b) /*通过比较

Hrbustoj 2266 Legendary Weights(辗转相除求最大公约数)

题意:这个题目的意思是给出一些砝码,问我们能不能根据这些砝码称量出任意重量的物品,最大公约数并不难求,难的在于如何建立这个模型. 思路:根据数论的基础知识,两个数a,b的最大公约数是a*x + b*y线性方程的最小正值(证明从略),所以很同意接受这个现实,当这些数的gcd为1的时候,线性方程可以表示(1,+OO)的任意整数,所以肯定可以.但这个题有一个坑点,那就是当最大公约数为2的时候也是可以的,加入物品重m,若m不可以被恰好表示出来,m总可以被控制在m-1和m+1的范围内,m是整数,所以可以确

辗转相除求最大公约数与最小公倍数

#include<stdio.h> int gcd(int a,int b) { if(b!=0) gcd(b,a%b); else return a; } int lcm(int a,int b) { return a*b/gcd(a,b);  //a/gcd(a,b)*b防溢出 } int main() { int a,b; while(scanf("%d%d",&a,&b)!=EOF){ printf("%d %d\n",gcd(a

辗转相减求最大公约数

#include <iostream> int main() { using namespace std; int m, n; cin >> n >> m; while (m != n) { while (m>n) { m = m - n; } while (n>m) { n = n - m; } } printf("%d\n", m); system("pause"); return 0; } 运行结果:

辗转相处法求最大公约数【C语言】

#include<stdio.h>int main(){    int a,b,r;    scanf("%d%d",&a,&b);    r=a%b;    while(r!=0)    {        a=b;        b=r;        r=a%b;    }    printf("%d",b);    return 0;}

求两个正整数的最大公约数——辗转相减法

问题:求解两个正整数的最大公约数 今天第一节形式化方法课,举了一个简单的例子——辗转相减法求解两个正整数的最大公约数,来讲解形式化方法的基本内容,让我们有感性的认识.其基本思路如下: 1.任意给定两个正整数a和b: 2.若a和b不相等,则执行第3步: 3.选择a.b中较大者,将较大者与较小者的差赋值给较大者: 4.判断重新赋值后的a和b是否相等,若不相等则继续执行第3步,否则执行第5步: 5.返回a或b. 程序如下(Java编写). 程序中前断言和后断言是形式化方法中的内容,前断言判断用于计算的

C语言 &#183; 求最大公约数

算法提高 求最大公约数 时间限制:1.0s   内存限制:512.0MB 编写一函数gcd,求两个正整数的最大公约数. 样例输入: 5 15样例输出:5 样例输入: 7 2样例输出:1 作者注释:常用两种方法:递归法,相减法. 递归法代码: 1 #include<stdio.h> 2 //递归求最大公约数 3 int gcd(int m,int n) 4 { 5 return n==0?m:gcd(n,m%n); 6 } 7 int main(){ 8 int m,n; 9 scanf(&qu

[算法]求满足要求的进制(辗转相除(欧几里得算法),求最大公约数gcd)

题目 3在十进制下满足若各位和能被3整除,则该数能被3整除. 5在十六进制下也满足此规律. 给定数字k,求多少进制(1e18进制范围内)下能满足此规律,找出一个即可,无则输出-1. 题解 写写画画能找到规律,即是求与k互质的数x,x进制下即能满足上述规律. 相关 求最大公约数:辗转相除法(又叫欧几里得算法) 欧几里德定理:gcd(a, b) = gcd(b , a mod b) ,对于正整数a.b. 其中a.b大小无所谓.当a值小于b值时,算法的下一次递归调用就能够将a和b的值交换过来. 代码

更相减损术求最大公约数-C

可参照辗转相除 1 #include<stdio.h> 2 3 int main(void) 4 { 5 int x=260; 6 int y=104; 7 8 int temp; //临时变量 9 10 int index=0; 11 while((x%2==0)&&(y%2==0)) 12 { 13 x/=2; 14 y/=2; 15 ++index; 16 } 17 18 while(x!=y) 19 { 20 temp=x-y; 21 if(temp<y) 22