OnlyPersistVictory DayTwo

B

题意:
有两只青蛙,青蛙 A A A和青蛙 B B B。他们在一个长度为 L L L米的圆形操场上,青蛙 A A A初始在坐标 a a a上,每次跳跃可以跳 m m m米,青蛙 B B B初始在坐标 b b b上,每次跳跃可以跳 n n n米。
两只青蛙在任意时刻的跳跃次数都是相同的,问至少跳多少次两者会相遇。
数据范围:
a ≠ b , 0 ≤ a , b < 2 × 1 0 9 , 0 < m , n < 2 × 1 0 9 , 0 < L < 2.1 × 1 0 9 a\neq b,0\leq a, b<2\times 10^9,0<m,n<2\times 10^9,0<L<2.1\times 10^9 a=b,0a,b<2×109,0<m,n<2×109,0<L<2.1×109

题解:
考虑两只青蛙距离差为: b − a b-a ba,设青蛙 A , B A,B A,B需要跳跃 x x x次才能相遇,
则有等式: ( n − m ) x ≡ ( b − a ) ( m o d    L ) (n-m)x\equiv (b-a)(\mod L) (nm)x(ba)(modL)
转换一下: ( n − m ) x + L y = ( b − a ) (n-m)x+Ly=(b-a) (nm)x+Ly=(ba)

(这里要注意 ( n − m ) (n-m) (nm) L L L都要为正数,所以当 ( n − m ) < 0 (n-m)<0 (nm)<0,可以乘上一个 − 1 -1 1使得等式转换为: ( m − n ) x + L × ( − y ) = a − b (m-n)x+L\times(-y)=a-b (mn)x+L×(y)=ab

通过 e x g c d exgcd exgcd可以求出一个 x 0 x_0 x0,然后扩大 b − a g c d ( n − m , L ) \frac{b-a}{gcd(n-m,L)} gcd(nm,L)ba倍。
由于 x 1 = x 0 + k L g c d ( n − m , L ) x_1=x_0+k\frac{L}{gcd(n-m,L)} x1=x0+kgcd(nm,L)L,所以对整体取模即可,注意负数问题皆可抛给 k k k,因此实际用的是 a b s ( L g c d ( n − m , L ) ) abs(\frac{L}{gcd(n-m,L)}) abs(gcd(nm,L)L)这个值。

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

typedef long long ll;
ll exgcd(ll a, ll b, ll &x, ll &y) {
    if(!b) {
        x = 1;
        y = 0;
        return a;
    }
    
    ll d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    
    return d;
}

int main()
{
    ll sta, stb, m, n, L;
    scanf("%lld%lld%lld%lld%lld", &sta, &stb, &m, &n, &L);
    ll a = m - n, b = L;
    ll x, y;
    ll g = exgcd(a, b, x, y);
    if((stb - sta) % g)  puts("Impossible");
    else {
        x *= (stb - sta) / g;
        ll mod = b / g;
        if(mod < 0) mod = -mod;
        printf("%lld\n", (x % mod + mod) % mod);
    }
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值