美文网首页
poj 1060---青蛙的约会(加深对扩展GCD的理解,然而是

poj 1060---青蛙的约会(加深对扩展GCD的理解,然而是

作者: Anxdada | 来源:发表于2017-03-05 15:45 被阅读0次

    连接

    题意:
    问最少要跳跃几次两只青蛙才能见面.
    思路:
    根据题意,两个青蛙跳到同一个点上才算是遇到了,所以有 (x+mt) - (y+nt) = p * k; (t是跳的次数,k是a青蛙跳的圈数跟b青蛙的圈数之差。整个就是路程差等于纬度线周长的整数倍),
    转化一下: (n-m) * t + k * p = x – y;
    令 a = n-m, b = k, c = gcd(a, b), d = x-y;
    有 a * t + b * p = d; (1)
    要求的是t的最小整数解。
    用扩展的欧几里德求出其中一组解t0 ,p0, 并令c = gcd(a, b);
    有 a * t0 + b * p0 = c; (2)
    因为c = gcd(a, b), 所以 a * t / c是整数,b * t / c 也是整数,所以 d / c 也需要是整数,否则无解。
    (2)式两边都乘(d / c) 得 a * t0 (d / c) + b * p0 * (d / c) = d;
    所以t0 * (d / c)是最小的解,但有可能是负数。
    因为a * ( t0 (d / c) + bn) + b * (p0 * (d / c) – a
    n) = d; (n是自然数)
    所以解为 (t0 * (d / c) % b + b) % b;

    所以根据思路,有以下代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define ll long long
    #define db double
    using namespace std;
    ll x,y,c;
    
    ll exgcd(int a,int b)
    {
        if(!b){
            x=1;
            y=0;
            c=a;
        }
        else{
            exgcd(b,a%b);
            ll tmp=x;
            x=y;
            y=tmp-a/b*y;
        }
    }
    
    int main()
    {
        ll a,b,d,x1,y1,m,n,l,flag=0;
        cin >> x1 >>y1>>m>>n>>l;
        if(m==n)
            flag=1;
        else{
            a=n-m;
            b=l;
            d=x1-y1;
            exgcd(a,b);
            if(d%c)//根据定义,如果除不尽就无解.
                flag=1;
        }
        if(flag)
            cout << "Impossible" << endl;
        else{
            b/=c;
            d/=c;
            cout << ((x*d)%b+b)%b <<endl;
        }
    }
    

    相关文章

      网友评论

          本文标题:poj 1060---青蛙的约会(加深对扩展GCD的理解,然而是

          本文链接:https://www.haomeiwen.com/subject/esfegttx.html