算法学习 之 欧几里得算法和扩展欧几里得算法(一)

这是我算法学习标签下的第一篇随笔,首先我想声明,在看了很多博客后,我的想法就是,尽量不去盲目复制别人的东西,一个原因是盲目复制不一定能发现其文章中的错误,二是可以加深自己的理解程度,并且将博客写得通俗易懂,转载别人的东西一定要注明出处。还有我的一个习惯就是,把东西写短一点,所以有可能会将一个本来应在一篇文章的东西,写成好几节。



Euclid Algorithm 又称辗转相除法,用途是求两个正整数a,b的最大公约数,gcd(a,b )表示a和b的最大公约数(gcd = greatest common divisor)。

内容:gcd(a,b)=gcd(b,a%b);

条件:a,b>0(当a%b=0时,使用该公式后就不能再使用)

关于最大公约数:前提是对于两个正整数而言,约数也必须是正整数。不会讨论 -4 8、4 0 等类似数的最大公约数,可以说是-4和8没有最大公约数,4和0也没有最大公约数。虽然对于次算法运行起来这两个是有结果的,-4和4。

证明:

将a表示为 a=kb+r,则 r=a%b , r=a-kb;

假设d为a,b的一个公约数,则a%d = 0 , b%d = 0  , 又r = a - kb,所以r % d = 0;

整理下:b % d = 0 , r % d = 0( (a % b) % d = 0 )

即 d也是b和a%b的公约数,所以a和b的最大公约数也是b和a%b的最大公约数。

递归形式代码:

#include<iostream>
using namespace std;

int gcd(int a,int b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}

int main()
{
    int a,b;
    cout<<"Please enter two integers:"<<endl;
    cin>>a>>b;
    cout<<a<<" and "<<b<<"‘s gcd is:"<<endl;
    cout<<gcd(a,b)<<endl;
return 0;
}

非递归形式:

#include<iostream>
using namespace std;

int gcd(int a,int b)
{
    int temp;
    while(b!=0)
    {
        temp=b;
        b=a%b;
        a=temp;
    }
    return a;
}

int main()
{
    int a,b;
    cout<<"Please enter two integers:"<<endl;
    cin>>a>>b;
    cout<<a<<" and "<<b<<"‘s gcd is:"<<endl;
    cout<<gcd(a,b)<<endl;
return 0;
}

运行截图:

有两点想说明的是:

1.出现类似gcd(4,0) 的含义并不是直接代表gcd(4,0)=4,因为4和0的公约数不存在。而是由前面的,得到了gcd(4,0),某个数mod 4 = 0,即有个数被4整除了,所以最大公约数是4。

2.网上有很多代码先判断了a与b的大小,a<b时候,要交换a与b的值。其实当a<b的时候,temp=b; b=a%b; a=temp;  就是一个swap的过程,所以交换位置是没有必要的。求gcd(4,8)=gcd(8,4)=...。

时间: 2024-10-11 08:31:53

算法学习 之 欧几里得算法和扩展欧几里得算法(一)的相关文章

算法学习 之 欧几里得算法和扩展欧几里得算法(二)

关于扩展欧几里得算法(Extended Euclidean Algorithm),我是在做青蛙的约会这一经典题目才接触到这个算法的.后面也有关于这一题的AC代码和解题思路. 内容:已知a, b,求解一组x,y,使它们满足贝祖等式: ax+by =gcd(a, b) 扩展欧几里得算法,就和它的名字一样是对欧几里得算法的扩展.何为扩展?一是,该算法保留了欧几里得算法的本质,可以求a与b的最大公约数.二是,已知a, b求解二元一次方程ax+by =gcd(a, b)的一组解(x,y). 证明: 假设 

算法学习 之 欧几里得算法和扩展欧几里得算法(三 完)

就像之前说的,接触到扩展欧几里得算法,是由于做到了这一题SWUST OJ 青蛙的约会之二(0481) http://www.cnblogs.com/haveyoueverbeen/p/4483218.html (查看题目信息可以戳上面的地址) 解题思路: 设输出结果为 s,则(m*s+x)-(n*s+y)= kl (k∈Z),即(n-m)*s + kl = x-y,设 a=n-m,b=l,c=x-y,即as +bk=c (ax+by=c),求最小正整数x,然后用扩展欧几里得算法,得到一组解x0 

noip知识点总结之--欧几里得算法和扩展欧几里得算法

一.欧几里得算法 名字非常高大上的不一定难,比如欧几里得算法...其实就是求两个正整数a, b的最大公约数(即gcd),亦称辗转相除法 需要先知道一个定理: gcd(a, b) = gcd(b, a mod b) (其中a mod b != 0)  或  b (其中a mod b == 0) 证明: 后半部分呢...是废话,于是只要证明前半部分即可. 不妨设g = gcd(a, b),于是有 a = g * A, b = g * B 且 (A, B) = 1 故gcd(b, a mod b) =

回档|欧几里得算法和扩展欧几里得算法

欧几里得算法:用于求两个非负整数a.b的最大公因数(用gcd(a,b)表示).这里用d表示,假设d一定存在. 证明:由题设知d|a,d|b(d|a代表d能整除a,即a mod d=0) 设a=kb+r,这里k和r都是整数.则r=a mod b.        我们可以让a=n1d,b=n2d.则r=(n1-k*n2)d        ∴d|r  ∴gcd(a,b)=gcd(b,a mod b) 扩展的欧几里得算法: 对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数

欧几里得算法和扩展欧几里得算法

1 实现代码: #include <iostream> 2 using namespace std; 3 4 void exgcd(long long a, long long b, long long &d, long long &x, long long &y) { 5 if (b == 0) { 6 d = a, x = 1, y = 0; 7 } 8 else { 9 exgcd(b, a%b, d, y, x); y-=a/b*x; 10 } 11 } 12

【算法学习笔记】26.扫描维护法 解题报告 SJTU_OJ 1133 数星星

SJTU OJ 1133. 数星星 Description 主任和小伙伴晚上非常无聊,于是带着他的宠物狗出来走走.主任突然发现天空中有一条长度为N的字符串,里面的字符都是大写字母.于是主任和他的小伙伴们开始数星星(STAR). 主任和他的小伙伴还有宠物狗数星星的数法不太一样.小伙伴是一个很教条的人,他只喜欢有规则的东西.所以他每次会在字符串里面找最早的’S’,然后找’S’之后最早的’T’,然后找’T’之后最早的’A’,最后找’A’之后最早的’R’.也就是找一个位置最靠前的STAR的子序列.每次找

扩展欧几里得算法学习记

话说以前我刷noip题的时候就想学这个东西了,结果却一直拖到了现在…… 到了高二才会这种东西的我实在是个蒟蒻啊! 将扩展欧几里得算法之前,先讲讲欧几里得算法是什么:gcd(a,b)=gcd(b,a%b).很显然是不?但我们还是要给出证明(设r=a%b): 设x是a,b的一个公约数,由于存在k使得a=k*b+r,又由于a|x,b|x,则有r|x,所以x是b,r的公约数 设x是b,r的一个公约数,因为存在k使得a=k*b+r,且b|x,r|x,那么a|x,所以x是a,b的公约数 综上所述,a和b的所

扩展欧几里得算法------扩展欧几里德算法

扩展欧几里得算法及其应用 一.扩展欧几里得算法 扩展欧几里得算法:对于不完全为 0 的非负整数 a,b,若gcd(a,b)表示 a,b 的最大公约数,必然存在整数对x,y ,使得 ax+by = gcd(a,b). 算法过程: 设 a>b,当 b=0时,gcd(a,b)=a.此时满足ax+by = gcd(a,b)的一组整数解为x=1,y=0:当a*b!=0 时, 设 a*x1+b*y1=gcd(a,b):b*x2+(a mod b)*y2=gcd(b,a mod b): 根据欧几里得原理知 g

扩展欧几里得算法的模板实现

我居然现在还记不住扩欧的板子,我太弱啦! 扩展欧几里得算法解决的是这样的问题: 给定一个不定方程组ax+by=gcd(a,b),求他的一组整数解 先给出实现代码 void exgcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0;//gcd(a,0)显然等于1*a-0*0=a return a; } int ans=exgcd(b,a%b,x,y); int tem=x; x=y; y-=tem-(a/b)*y; return ans;} 但实