• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
dwtfukgv
博客园    首页    新随笔    联系   管理    订阅  订阅
POJ 1061 青蛙的约会(扩展欧几里德算法)

题意:两只青蛙在同一个纬度上跳跃,给定每个青蛙的开始坐标和每秒跳几个单位,纬度长为L,求它们相遇的最短时间。

析:开始,一看只有一组数据,就想模拟一下,觉得应该不会超时,但是不幸的是TLE了,我知道这肯定是一个数学题,不过刚开始没想到是扩展欧几里德,后来才发现这个可以转化为这个算法。

我们假设刚开始它们的坐标分别是x,y,它们的速度分别是m,n,坐标轴长为L,那么经过t次跳跃后它们的距离之差就是L(想一想是不是,可以画图看看)。

所以(mt-x) - (nt-y) = kL;可转化为kL + (n-m)t = x - y。只有满足gcd(L, n-m) 是x-y的倍数才有解。

通过扩展欧几里德求得是t不一定是正数,所以我们要求最小的非负整数,tt = L / d, t = (t % tt + tt) % tt。

代码如下:

#include <iostream>

using namespace std;
typedef long long LL;

void exgcd(LL a, LL b, LL &d, LL &x, LL &y){
    if(!b){ d = a;  x = 1;  y = 0;  }
    else { exgcd(b, a%b, d, y, x);  y -= x * (a/b); }
}

int main(){
    LL n, m, xx, yy, d = 0, l, k, t;
    cin >> xx >> yy >> m >> n >> l;
    exgcd(l, n-m, d, k, t);
    if((xx-yy) % d != 0)  cout << "Impossible\n";
    else{
        t = t * ((xx-yy)/d);
        LL tt = l / d;
        t = (t % tt + tt) % tt;
        cout << t << endl;

    }
    return 0;
}

 

posted on 2016-05-22 20:47  dwtfukgv  阅读(188)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3