The equation 之深入理解扩展欧几里得

来源:互联网 发布:东北师大网络教育 编辑:程序博客网 时间:2024/05/16 17:15

为了更加深入的理解和应用欧几里得和扩展欧几里得算法,选择这样的一个题目来进行详细讲述:

The equation  http://acm.hust.edu.cn/vjudge/contest/view.action?cid=109329#problem/H

由于此题目需要分析的思路和过程比较多,除了代码实现外,我就直接手写了,字体有待改进,敬请谅解。

不带返回值的扩展欧几里得代码实现:(和上面相比,也算是另外一种编码方式了)

void extend_gcd(long long a,long long b,long long &x,long long &y){    if(b==0)    {        x=1;        y=0;        return;    }    extend_gcd(b,a%b,y,x);    y-=a/b*x;    return;}









罗里吧嗦说了一堆,最后,代码实现如下:

#include <iostream>#include <cstdio>#include <cmath>using namespace std;inline long long GMAX(long long &x,long long &y){    return x>y?x:y;}inline long long GMIN(long long &x,long long &y){    return x<y?x:y;}long long gcd(long long a, long long b){    if(b==0) return a;    else return gcd(b,a%b);}void extend_gcd(long long a,long long b,long long &x,long long &y){    if(b==0)    {        x=1;        y=0;        return;    }    extend_gcd(b,a%b,y,x);    y-=a/b*x;    return;}int main(){    long long a,b,c,x1,x2,y1,y2;    long long x0,y0;    while(scanf("%lld%lld%lld",&a,&b,&c)!=EOF)    {        scanf("%lld%lld",&x1,&x2);        scanf("%lld%lld",&y1,&y2);        c=-c;        if(c<0)        {            a=-a;            b=-b;            c=-c;        }        if(a<0)  //相当于调换了x轴        {            a=-a;            long long t=x1;            x1=-x2;            x2=-t;        }        if(b<0)        {            b=-b;            long long t=y1;            y1=-y2;            y2=-t;        }        if(a==0 && b==0)        {            if(c==0)            {                printf("%lld\n",(x2-x1+1)*(y2-y1+1));            }            else printf("0\n");        }        else if(a==0)        {            if(c%b==0)            {                if(c/b>=y1&&c/b<=y2)                {                    printf("%lld\n",x2-x1+1);                }                else printf("0\n");            }            else printf("0\n");        }        else if(b==0)        {            if(c%a==0)            {                if(c/a>=x1&&c/a<=x2)                {                    printf("%lld\n",y2-y1+1);                }                else printf("0\n");            }            else printf("0\n");        }        else        {            long long M=gcd(a,b);            if(c%M)            {                printf("0\n");            }            a=a/M;            b=b/M;            c=c/M;            extend_gcd(a,b,x0,y0); //求的是=gcd(a,b)的值,所以下面要都*c            x0=x0*c;            y0=y0*c;            long long low1=ceil(1.0*(x1-x0)/b);            long long high1=floor(1.0*(x2-x0)/b);            long long low2=ceil(1.0*(y0-y2)/a);            long long high2=floor(1.0*(y0-y1)/a);            long long l=GMAX(low1,low2);            long long h=GMIN(high1,high2);            if(l>h)            {                printf("0\n");            }            else printf("%lld\n",h-l+1);        }    }    return 0;}






1 0