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

posted @ 2010-09-11 09:51  菜到不得鸟  阅读(693)  评论(0)    收藏  举报