POJ 1061 扩展欧几里得
假若相遇,则存在 x+ms≡y+ns(mod l)
=>(x+ms)-(y+ns)=kl;
=>x-y-(n-m)s=kl;(已知x,y,n,m,l)
=>kl+(n-m)s=x-y;
即求满足 kl+bs=a(已知 l,b,a)最小的s;
——————————
扩展欧几里德算法-求解不定方程,线性同余方程:
解不定方程ax + by = n的步骤如下:
(1)计算gcd(a, b). 若gcd(a, b)不能整除n,则方程无整数解;否则,在方程的两边同除以gcd(a, b),
得到新的不定方程a'x + b'y = n',此时gcd(a', b') = 1
(2)求出不定方程a'x + b'y = 1的一组整数解x0, y0,则n'x0,n'y0是方程a'x + b'y = n'的一组整数解。
(3)根据&$#@定理,可得方程a'x + b'y = n'的所有整数解为:
x = n'x0 + b't
y = n'y0 - a't
(t为整数)
这也就是方程ax + by = n的所有整数解
利用扩展的欧几里德算法,计算gcd(a, b)和满足d = gcd(a, b) = ax0 + by0的x0和y0,
也就是求出了满足a'x0 + b'y0 = 1的一组整数解。因此可得:
x = n/d * x0 + b/d * t
y = n/d * y0 - a/d * t
(t是整数)
——————————
注意扩展欧几里得求解的是a'x+b'y=1的x,y的解,其中a',b'是a/gcd(a,b),b/gcd(a,b) a,b为你输入的两个数。
例如你输入3,5和输入6,10一样x=2,y=-1,只是返回的gcd不一样而已。
#include"stdio.h"
__int64 gcd(__int64 a,__int64 b)
{
return b?gcd(b,a%b):a;
}
void egcd(__int64 a,__int64 b,__int64 &x,__int64 &y)//已求出gcd,故不需要返回
{
__int64 tmp,i;
if(!b)
{
x=1;y=0;
return ;
}
else{
egcd(b,a%b,x,y);
tmp=x;
x=y;
y=tmp-(a/b)*y;
}
return ;
}
int main()
{
__int64 x,y,m,n,l;
__int64 a,b,d,k,s,t;
while(scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&l)!=EOF)
{
a=n-m;
b=l;
d=x-y;
__int64 r=gcd(a,b);
if(d%r)
{
printf("Impossible\n");
}
else
{
a/=r;
b/=r;
d/=r;
egcd(a,b,s,k);
s*=d;
k*=d;
t=s/b;
s-=t*b;
if(s<0)
s+=b;
printf("%I64d\n",s);
}
}
return 0;
}
浙公网安备 33010602011771号