例1.3-2青蛙的约会

问题描述:

数轴为首尾相接,青蛙A和青蛙B同时开始往正方向跳。A从x开始,每次跳m个单位长度;B从y开始,每次跳n个单位长度。数轴总长为L。求它们跳了几次后能够相遇。

要求:输入一行五个整数,x,y,m,n,L, 其中x!=y,输出一行一个数,表示碰面所需要的跳跃次数,如果永远不可能碰面,则输出一行Impossible.

分析:

设t为跳跃次数,p为A和B跳跃圈数之差,则有下式:

(x+m*t)-(y+n*t)=p*L       (1)

(n-m)*t+L*p=x-y             (2)

记 a=n-m,b=L,d=x-y,c=GCD(a,b)  则:

a*t+b*p=d                       (3)

求t的最小整数解。

步骤:

step1:

       利用扩展欧几里得算法解a*t+b*p=c的一组最小解解(t0.p0)

step2:

       若d不能整除c,则无解;

       若d能整除c:

                    (3)式两边同乘d/得(3)式的一个最小解为(t0*d/c,p0*d/c)

                  (但有可能是负数)

                    由于a*(t0*(d/c)+b*n)+b*(p0*(d/c)-a*n)=d, n为自然数

                     所以解为(t0*(d/c)%b+b)%b????????

代码:

#include<iostream>
using namespace std;

int extended_gcd(int a,int b,int &x,int &y)
{
    int ret,tmp;
    if(!b)
    {
        x=1;y=0;
        return a;
    }
    ret=extended_gcd(b,a%b,x,y);
    tmp=x;
    x=y;
    y=tmp-a/b*y;
    return ret;
}

int x,y,m,n,L;//题中所给已知量
int gcd;
int x0,y0;//a*x+b*y=c的一组解
int main()

{
    cin>>x>>y>>m>>n>>L;
    gcd=extended_gcd(n-m,L,x0,y0);
    if((x-y)%gcd!=0)
        cout<<"Impossible"<<endl;
    else
        cout<<((long long)x0*(x-y)/gcd%L+L)%L<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sdau20171989/article/details/81271342