• 【POJ1061】【洛谷P1516】青蛙的约会


    问题描述

    输入格式

    输出格式

    样例输入

    1 2 3 4 5

    样例输出

    4

    题解

    已知两只青蛙的初始位置和每一步跳的距离,求两只青蛙跳到同一点的最短时间,设最小时间为t,可得:

    (x+m*t)-(y+n*t)=p*L

    这个式子是个二元一次方程,而我们学过用扩展欧几里德求二元一次方程的解,其中二元一次方程的形式为

    a*x+b*y=c

    把上面的式子转化成相似形式可得

    (n-m)*t+L*p=x-y  (*)

    令:a=n-m, b=L, c=gcd(a,b), d=x-y

    得:a*t+b*p=d  (1)

    那么我们可以用扩展欧几里德求出一组t0,p0,使得

    a*t0+b*p0=c  (2)

    (1)式两边同除c得:a*t/c+b*p/c=d/c

    易知a*t/c和b*p/c是整数,所以d/c也是整数,否则无解。

    (2)式两边同乘(d/c)得:a*t0*(d/c)+b*p0*(d/c)=d

    所以t0*(d/c)为最小的解,但有可能为负数,为使最终答案为正,解为

    (t0*(d/c)%(b/c)+(b/c))%(b/c)

    本题有个陷阱,两只青蛙谁在前谁在后是不确定的,但我们可以通过调整使第一只青蛙在前。

     1 #include <cstdio>
     2 #define ll long long
     3 ll exgcd(ll a,ll b,ll &x,ll &y)
     4 {
     5     if (!b)
     6     {
     7         x=1,y=0;
     8         return a;
     9     }
    10     ll ans=exgcd(b,a%b,x,y),t;
    11     t=x,x=y,y=t-a/b*y;
    12     return ans;
    13 }
    14 int main()
    15 {
    16     ll gcd,X,Y,x,y,m,n,l,a,b,c,t;
    17     scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);
    18     a=n-m,c=x-y;
    19     if (a<0) a=-a,c=-c;
    20     gcd=exgcd(a,l,X,Y);  b=l/gcd;
    21     if (c%gcd) printf("Impossible");
    22     else printf("%lld",(c/gcd*X%b+b)%b);
    23     return 0;
    24 } 
  • 相关阅读:
    量化学习 | 配对交易 backtrader实现
    量化学习 | Tushare 基本面选股 (二)
    CVPR 2020 三篇有趣的论文解读
    量化学习 | Tushare和Backtrader初探(一)
    解决deepin网卡耗电异常及网速慢的问题
    linux省电三步骤
    扎心了
    解决IDEA卡在Resolving Maven dependencies问题
    关于生产环境和开发环境的介绍
    jQuery事件委托
  • 原文地址:https://www.cnblogs.com/rabbit1103/p/13499624.html
Copyright © 2020-2023  润新知