直接用欧几里得
AX+BY=gcd(A,B);
问题里s(n-m)+k*l=x-y
所以存在s,k的整数解的话就要 (x-y)%gcd(n-m,l)
再分情况考虑n-m是否是正负 枚举k得出解
View Code
#include<stdio.h>
__int64 gcd(__int64 m,__int64 n)
{
__int64 t;
while(n!=0)
{
t=m%n;
m=n;
n=t;
}
return m;
}
int main()
{
__int64 x,y,m,n,l;
while(scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&l)!=EOF)
{
__int64 t=m-n;
if(t<0)t=-t;
__int64 g;
if(t>l)
{
g=gcd(t,l);
}
else
{
g=gcd(l,t);
}
if((y-x)%g!=0)
{
printf("Impossible\n");
}
else
{
int i;
if((n-m)>0)
for(i=0;;i++)
{
if((x-y+i*l)%(n-m)==0&&(x-y+i*l)/(n-m)>0)
{
printf("%I64d\n",(x-y+i*l)/(n-m));
break;
}
}
else
for(i=0;;i++)
{
if((x-y-i*l)%(n-m)==0&&(x-y-i*l)/(n-m)>0)
{
printf("%I64d\n",(x-y-i*l)/(n-m));
break;
}
}
}
}
}
同余方程:
问题转化为:
求满足 (m-n)*t+Lp=(y-x) 的最小 t (t>0)即求
一次同余方程 (m-n)*t = (y-x) (mod L) 的最小正整数解
View Code
#include<stdio.h>
__int64 Ext_gcd(__int64 a,__int64 b,__int64 &x,__int64 &y)
{
if(b==0) { x=1, y=0; return a; }
__int64 res= Ext_gcd(b,a%b,y,x);
y-= a/b*x;
return res;
}
__int64 Ax_b_mod_n(__int64 a,__int64 b,__int64 n)//同余方程 (m-n)*t = (y-x) (mod L) 的最小正整数解
{
__int64 res,x,y,t;
res= Ext_gcd(a,b,x,y);
if(n%res==0)
{
x= x*n/res;
t= b/res;
if(t<0) t=-t;
x= (x%t+t)%t;
return x;
}
return -1;
}
int main()
{
__int64 x,y,m,n,len,t;
scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&len);
t= Ax_b_mod_n(m-n,len,y-x);
if(t==-1) printf("Impossible\n");
else printf("%I64d\n",t);
}