poj 1061(数论之欧几里德及其扩展)

点击打开链接


假设青蛙都跳t步;

A xx+mt;

B yy+nt;

如果相遇 xx+mt-yy-nt=kl;

则(n-m)t+kl=xx-yy;

则可以转化为偶几米得问题ax+by=c;--B

a=(n-m),b=l;

我们知道ax0+by0=d  --A

d=Gcd(a,b);

根据欧几里德的扩展可以求出x0,y0,然后A式*c/d可以转化为B式,

注意其中一点 l=l/d;

注意结果<0时,+l,


欧几里德算法

int Euclid(int a,int b)
{
if(b == 0)
        return a;
else
        return Euclid(b,mod(a,b));
}


附:取模运算
int mod(int a,int b)
{
if(a >= 0)
        return a % b;
else
        return a % b + b;
}


欧几里德扩展算法:
int exGcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
int r = exGcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
    return r;
}



#include"stdio.h"
#include"string.h"
#include"math.h"
typedef __int64 int64;
int64 x,y;
int64 fun(int64 a,int64 b)
{
	if(a>=0)return a%b;
	else return a%b+b;
}
int64 exGcd(int64 a,int64 b)
{
	if(b==0)
	{
		x=1;y=0;
		return a;
	}
	int64 t;
	int64 d=exGcd(b,a%b);
	t=x;
	x=y;
	y=t-a/b*y;
	return d;
}
int main()
{
	int64 xx,yy;
	int64 n,m,l;
	int64 c,d;
	while(scanf("%I64d%I64d%I64d%I64d%I64d",&xx,&yy,&m,&n,&l)!=-1)
	{
		if(m>n)
		{
			d=exGcd(m-n,l);
			c=yy-xx;
		}
		else 
		{
			d=exGcd(n-m,l);
			c=xx-yy;
		}
		l/=d;
		if(c%d)
			printf("Impossible\n");
		else
			printf("%I64d\n",fun(x*c/d,l));
	}
	return 0;
}


你可能感兴趣的:(poj 1061(数论之欧几里德及其扩展))