pku 1061 青蛙的约会(线性同余方程)
此题暴力求解必定超时,一般计算机计算一亿次就为一秒,L超过了20亿所以显然不行。其中一种方式是利用相对性,把速度慢的青蛙看成静
止,而速度快的青蛙去追赶速度慢者。设m速度快 n速度慢,那么他们开始距离就为dist=(y-x+l)%l。设m青蛙的坐标为0,n青蛙坐标为dist
且设经过k时间,跑了i圈之后m青蛙跑到了n青蛙的坐标。那么就有下列式子:
(m-n)*k==l*i+dist;
假如p为(m-n)与l的最大公约数gcd(m-n,l),那么若dist%p不为零,直接就可以判断为不可行的。而且dist%p为零时是一定可行的,具体
原因讲第二种方法时再解释,先看第一种方法的解法:
//344MS
#include <stdio.h>
long long x,y,m,n,l,dist;
int gcd(int a,int b)
{
if(b==0)return a;
return gcd(b,a%b);
}
int main()
{
// freopen("tdata.txt","r",stdin);
while(scanf("%I64d %I64d %I64d %I64d %I64d",&x,&y,&m,&n,&l)!=EOF)
{
if(m>n)dist=(y-x+l)%l;
else
{
dist=(x-y+l)%l;
int temp=m;
m=n;
n=temp;
}
if(/*m==n||*/dist%gcd(m-n,l))
{
printf("Impossible\n");
continue;
}
long long k=0;
for(int i=0;; i++)
{
if((i*l+dist)%(m-n)==0)
{
k=(i*l+dist)/(m-n);
break;
}
}
printf("%I64d\n",k);
}
return 0;
}
//******************************************************************************************************
两只青蛙跳了t 步
A的坐标 x+mt
B的坐标 y+nt
相遇的充要条件:
x+mt-y-nt= pL ( p是整数) 即
(n-m)*t+Lp=x-y (L>0)
问题转化为:
求满足 (m-n)*t+Lp=(y-x) 的最小 t (t>0)
即求 一次同余方程
(m-n)*t = (y-x) (mod L) 的最小正整数解
//0MS
#include <stdio.h>
typedef long long LL;
LL extgcd(LL a,LL b,LL &x,LL &y)
{//gcd(a,b) = ax + by
if(!b)
{
x = 1;
y = 0;
return a;
}
LL g = extgcd(b,a%b,x,y);
LL t = x;
x = y;
y = t - (a / b) * y;
return g;
}
inline LL _abs(int x)
{
return x > 0 ? x : -x;
}
bool modeq(LL a,LL c,LL m,LL &x)
{//ax (=) c (mod m) -> ax - my = c
LL g,y;
g = extgcd(a,m,x,y); // g = gcd(a,m) = ax - my
// printf("g=%I64d\n",g);
if( c%g )return false;
else
{
x = (c/g * x) % m;
x %= _abs(m/g);
if(x<0) x += _abs(m/g);
return true;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("tdata.txt","r",stdin);
#endif
LL x,y,m,n,L;
LL A,C,M,X0;
while(scanf("%I64d %I64d %I64d %I64d %I64d",&x,&y,&m,&n,&L)!=EOF)
{
/* if(m==n)
{
printf("Impossible\n");
continue;
}*/
A = m-n;
C = y-x;
M = L;
/* if(A<0)
{
A=-A;
C=-C;
}*/
if(modeq(A,C,M,X0)) printf("%I64d\n",X0);
else printf("Impossible\n");
}
return 0;
}
浙公网安备 33010602011771号