扩展欧几里得算法——pku1061

直接用欧几里得
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);
}
原文地址:https://www.cnblogs.com/huhuuu/p/2029798.html