扩展欧几里得算法及其应用

来源:互联网 发布:怎么学好数据库 编辑:程序博客网 时间:2024/06/05 14:34

贝祖等式:对于不完全为0的两个非负整数,a,b;gcd(a,b)表示这两个数的最大公约数,则必然存在整数x,y,使得gcd(a,b)=ax+by。

对于给定的符合条件的a,b;如何求出相应的x,y呢?

用扩展欧几里得算法解决该问题。

先给出代码实现,再分析算法原理:

代码一(较为简单,来源360百科):

#include <iostream>using namespace std;int x,y,p;void Ep_gcd(int a,int b){    if(b==0)  {x=1;y=0;p=a;return;}    Ep_gcd(b,a%b);    int tem=x;    x=y;    y=tem-a/b*x;}int main(){    int a,b;    while(cin>>a>>b){            Ep_gcd(a,b);       cout<<"x is :"<<x<<"y is :"<<y<<endl;    }    return 0;}


代码二(较为精炼,来源百度百科)

#include <iostream>using namespace std;void Ep_gcd(int a,int b,int&d,int &x,int &y){    if(b==0) {d=a;x=1;y=0;return;}    Ep_gcd(b,a%b,d,y,x);    y-=a/b*x;}int main(){    int x,y,d,a,b;    while(cin>>a>>b){        Ep_gcd(a,b,d,x,y);        cout<<x<<' '<<y<<endl;    }    return 0;}

下面就来讲讲这个算法的实现原理:

由扩展欧几里得定理:

ax+by=gcd(a,b);

由欧几里得定理可以知道gcd(a,b)=gcd(b,a%b);

证:另r=a%b;则a=kb+r;

设d为a和b的公约数,则d|a,d|b;

由r=a-kb;则d|r。

设d为b和r的公约数,则d|b,d|r;

又a=kb+r;故d|a;

所以由上得到a,b,r的公约数相同,则他们的最大公约数也相同。

进一步分析:

由gcd(a,b)=gcd(b,a%b)得一下两个等式:

x1a+y1b=gcd(a,b);

x2b+y2a%b=gcd(b,a%b);

有x1a+y1b=x2b+y2a%b;

a%b=a-a/b*b;

化简得到x1a+y1b=y2a+b(x2-a/b*y2);

由系数对应关系得到:x1=y2;y1=x2-a/b*y2;


扩展欧几里得算法的应用:

问题:【直线上的点】 求直线ax+by+c=0上有多少个整点(x,y)满足x∈[x1,x2],y∈[y1,y2]

分析:

首先我们可以利用扩展欧几里得算法得到ax+by=gcd(a,b)的一组解(x1,y1),那么思考一下其他解呢?

任取另外一组解(x2,y2),有ax1+by1=ax2+by2;变形得到a(x1-x2)=b(y2-y1);

左右两边分别除以gcd(a,b),令a`=a/gcd(a,b),b`=b/gcd(a,b);

即a`(x1-x2)=b`(y2-y1);由于a`和b`互质,故而看ka`=(y2-y1),kb`=(x1-x2),其中k为任意整数。

则分别得到x2=x1-kb`,y2=y1+ka`;k可以取任意整数。


有了这样的结论,回到该问题,经过移项得到ax+by=-c;

可以推知如果-c是gcd(a,b)的整数倍时,则该方程有整数解,且设ax+by=gcd(a,b)的一组解为(x0,y0);

则该方程的解为(x0*(-c)/g,y0*(-c)/g);

否则该方程无整数解






原创粉丝点击