20160314 POJ1061青蛙的约会(拓展欧几里得)

关于拓展欧几里得算法

运用拓展欧几里得算法,可以求出GCD(a,b),并且求出一组满足AX+BY=GCD(A,B)。

1.当B==0时,X=1,Y=0等式成立

2.当B>0时,有

       BX'+(A mod B)Y'=GCD(B,A mod B)=GCD(A,B)

可以通过变形得到

      AY'+B(X'-A/B*Y')=GCD(A,B)

由此可得 X=Y‘,Y=X'-A/B*Y',当GCD(B,A mod B)进行至B==0时到达出口。

通解为 X+B/GCD(A,B)*C,Y+A/GCD(A,B)*C。为任意整数。

题意:

一直位于x速度为m的青蛙1与位于y速度为n青蛙2往同一个方向跳圈,圈长为L,问什么时候可以相遇。

思路:

依题意可列方程:(x+m*t)-(y+n*t)=p*L

整理得C*((n-m)*t+L*p)=x-y,C为任意正整数,由此可得如果GCD(n-m,L)*C=x-y,则符合拓展欧几里得方程的形式,此时t有解。

运用拓展欧几里得公式可得到t的一个解,通过X+B/GCD(A,B)*C找到最小的t的解,输出。

#include <iostream>

using namespace std;

typedef long long LL;

LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    else
    {
        LL r=exgcd(b,a%b,y,x);
        y-=x*(a/b);,
        return r;
    }

}
int main()
{
    LL x,y,m,n,L;
    LL A,B,X,Y,c;
    while(cin>>x>>y>>m>>n>>L)
    {
        A=n-m;
        B=L;
        c=x-y;
        LL r=exgcd(A,B,X,Y);
        if(c%r!=0)//c%r!=0的情况不符合拓展GCD的形式,此时t无解
        {
            cout<<"Impossible\n";
            continue;
        }
        X*=c/r;
        Y*=c/r;
        LL ans=X*r/B;//x=x0+B/GCD(A,B)*C,假设x为0,可得最接近0的解,此时C=x0/B/GCD(A,B)
        ans=X-ans*(B/r);//此时ans为最接近0的解
        if(ans<0)//为负数时变成最小的正数
            ans+=B/r;
        cout<<ans<<endl;
    }
    return 0;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值