• POJ-1061 青蛙的约会---扩展欧几里得算法


    题目链接:

    https://cn.vjudge.net/problem/POJ-1061

    题目大意:

    两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。
    我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。

    解题思路:

    假设t时刻相遇

    有:(x + mt) = (y + nt) (mod L)

    也就是 x + mt - y - nt  = K * L

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

    (因为K取任意整数,移到方程左端可以不管他的正负,反正对求出的K不处理)

    也就是:a * t + b * K = y - x   a = m - n   b = L 求解t和K

    特判 a = 0 的时候 x = y解为0,反之无解

    当a < 0时,标记一下,然后a取正数,最后求出的t再取一下相反数即可

    对于ax + by = c的求解

    先求解ax + by = gcd(a, b) 求出x0,y0

    如果gcd(x, y)整除c则有解,反之无解

    根据x0 y0可得到一解:

    x1 = x0 * c / gcd(a, b)

    y1 = y0 * c / gcd(a, b)

    所有解:

    x = x1 + b / gcd(a, b) * t

    y = y1 + a / gcd(a, b) * t

    最小正数x的解

    b` = b / gcd(a, b)

    a` = a / gcd(a, b)

    x2 = ((x1 % b`) + b`) % b`

    y2 根据x2计算出来

    同理可求出最小正数y的解

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 using namespace std;
     5 typedef long long ll;
     6 ll extgcd(ll a, ll b, ll&x, ll&y)//ax+by = gcd(a, b)的解。返回值为gcd
     7 {
     8     ll d = a;
     9     if(b)
    10     {
    11        d = extgcd(b, a % b, y, x);
    12        y -= (a / b) * x;
    13     }
    14     else x = 1, y = 0;
    15     return d;
    16 }
    17 int main()
    18 {
    19     ll x, y, m, n, l;
    20     cin >> x >> y >> m >> n >> l;
    21     ll xx, yy;
    22     ll a = m - n, b = l;
    23     if(a == 0)
    24     {
    25         if(x == y)cout<<"0"<<endl;
    26         else cout<<"Impossible"<<endl;
    27         return 0;
    28     }
    29     bool flag = 0;
    30     if(a < 0)a = -a, flag = 1;
    31     ll g = extgcd(a, b, xx, yy);
    32     if((y - x) % g)cout<<"Impossible"<<endl;
    33     else
    34     {
    35         xx = xx * (y - x) / g;
    36         if(flag)xx = -xx;
    37         l = l / g;
    38         xx = ((xx % l) + l) % l;
    39         cout<<xx<<endl;
    40     }
    41     return 0;
    42 }
  • 相关阅读:
    移动MM首届手机软件设计及创意大赛决赛取得圆满成功
    Windows Phone 7 EKB系列文章发布
    EVC3/4项目升级到Visual Studio项目的一些建议
    Windows Phone SDK 7.1 RTM 发布
    Howto: 创建Windows Phone 7自定义控件
    风云再起,7迹由你WP7技术沙龙上海站第二次活动
    Windows Phone Dev Notes如何使用ConnectionSettingsTask 来启动连接设置页面
    【OneNote Mobile】 如何处理便签内容的格式?
    《101 Windows Phone 7 Apps》读书笔记PASSWORDS & SECRETS
    3年MVP路,一颗感恩的心
  • 原文地址:https://www.cnblogs.com/fzl194/p/9038888.html
Copyright © 2020-2023  润新知