数论/扩展欧几里德算法

扩展欧几里德算法求的是二元一次方程ax+by=c,在a,b,c已知的情况下x的最小整数值,

扩展欧几里德算法:

int exgcd(int a,int b,int &X,int &Y) { if(b==0) { X=1; Y=0; return a; } int d=exgcd(b,a%b,X,Y); int t=X; X=Y; Y=t-(a/b)*Y; return d; }

int r=exgcd(a,b,X,Y)

当c%r==0时:

b/=r;

c/=r;

x的最小整数值x1=(c*X%b+b)%b

否则不存在x的最小整数解。

题目poj 1061

这题先列出式子,设跳了xi步之后他们会相遇。则有公式

(xi*m+x)-(xi*n+y)=kl(k=1,2,3.....)或者(xi*n+y)-(xi*m+x)=kl(k=1,2,3.....)

化简成xi(m-n)+kl=y-x或者xi(n-m)+kl=x-y。

刚好符合扩展欧几里德的公式要求,a=m-n(m>n)或者n-m(n>m),b=k,c=y-x(m>n)或者x-y(n>m),这样套扩展欧几里德公式求xi的最小正整数就行了,代码

#include<iostream> #include<cmath> using namespace std; __int64 exgcd(__int64 a,__int64 b,__int64 &X,__int64 &Y) { if(b==0) { X=1; Y=0; return a; } __int64 d=exgcd(b,a%b,X,Y); __int64 t=X; X=Y; Y=t-(a/b)*Y; return d; } int main() { __int64 x,y,m,n,L,X,Y,a,b,r,x1,c; while(scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&L)!=EOF) { a=m>n?m-n:n-m; b=L; c=m>n?y-x:x-y; r=exgcd(a,b,X,Y); if(c%r==0) { b/=r; c/=r; x1=(c*X%b+b)%b; printf("%I64d/n", x1); } else cout<<"Impossible"<<endl; } return 0; }

 

你可能感兴趣的:(数论/扩展欧几里德算法)