我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
根据题意我们可以知道这是一个欧几里得题
扩展欧几里得定理:对于2个不全为0的整数a,b必存在一组解x,y使得ax+by=gcd(a,b)
#include<stdio.h>
#include<math.h>
longlongx,y,q;
longlonggcd(longlonga,longlongb)
{
returnb==0?a:gcd(b,a%b);
}
longlonggcd_x(longlonga,longlongb)
{
longlongt,d;
if(b==0)
{
x=1;
y=0;
returna;
}
d=gcd_x(b,a%b);
t=x;
x=y;
y=t-(a/b)*(y);
returnd;
}
intmain()
{
longlonga,b,c,l,st1,st2,m,n,ans,k;
while(scanf("%lld%lld%lld%lld%lld",&st1,&st2,&m,&n,&l)==5)
{
a=n-m;
b=l;
c=st1-st2;
if(c%gcd(a,b)!=0)printf("Impossible\n");
else
{
ans=gcd_x(a,b);
x=x*(c/ans);
k=x/(b/ans);
x=x-k*(b/ans);
if(x<0)x=x+b/ans;
printf("%lld\n",x);
}
}
}
这段代码的意识:
intgcd_x(inta,intb)
{
intt,d;
if(b==0)
{
x=1;
y=0;
returna;
}
d=gcd_x(b,a%b);
t=x;
x=y;
y=t-(a/b)*(y);
returnd;
}
由于gcd(a,b)=gcd(b,a%b);a%b=a-a/b*b;
gcd(a,b)=ax+by=gcd(b,a%b)=bx1+(a%b)y1=y1*a+(x1-y1*a/b)*b
根据ab前对应系数相等知x=y1,y=x1-y1*(a/b)
上式xy是本层递归的xy(假设为gcd(a,b)中的xy)x1,y1是上次递归返回的
xy(gcd(b,a%b)中的xy)
故有
t=x;
x=y;
y=t-(a/b)*(y); 这几句代码求得xy的值
gcd(a,b)=gcd(b,a%b)=gcd.........=gcd(a,0)=ax+by=a
有一点我有点疑惑这时候ax+by=ax=1是毋庸置疑的但是y应该可以为任何数啊为什么非要为0啊???
k=x/(b/ans);
x=x-k*(b/ans);
if(x<0)x=x+b/ans;
上面三句是求最短的步数
由于通解是
X=x0+b/ans*t
Y=y0-a/ans*t
上面那三句就是求的最短的步数即大于0的最小的解