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; }