luoguP1516 青蛙的约会|数论|同余|扩展欧几里得算法

本文探讨了一道趣味数学问题“青蛙的约会”,通过应用扩展欧几里得算法来解决青蛙A和青蛙B在特定条件下能否相遇的问题。文章详细分析了算法原理,包括如何将问题转化为数学表达式,并给出了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

青蛙的约会|数论|同余|扩展欧几里得算法

为什么这种乐(S)观(B)的青蛙都能网恋,还成功了(我:???????SB青蛙去死8 青蛙

为什么最近一直在做青蛙的题?(我怕是要无限-1s制了????)

V3

Problem

Problem

分析

先搞懂扩展欧几里得算法8

根据题意可得:

青蛙A:

初始位置x,每次跳m

青蛙B:

初始位置y,每次跳n

总长度为L

求相遇时间(如果有解)t

即换成数学表达式:
\[ x+m\cdot t \equiv y+n\cdot t \left(mod \ L\right) \]
根据分析扩展欧几里得算法的步骤:
\[ L|\left(x+m\cdot t\right)-\left(y+n\cdot t \right) \]
=>
\[ L|\left(x-y\right)+\left(m-n\right)t \]
=>
\[ \left(x-y\right)+\left(m-n\right)t=kL,k\in Z^{*} \]

\[ n-m=a,x-y=b(a>0,b>0) \]
注意:

如果a<0:

需要把a和b调正:
\[ a=-a,b=-b \]


\[ a\cdot t+k\cdot L=b \]

方程有解:

当且仅当
\[ gcd\left(a,k\right)|b \]
如果有解:


\[ a\cdot t+L\cdot k=gcd\left(a,k\right) \]
根据扩展欧拉定理得一个解t0

之后对t0进行操作得到t的一个解:
\[ t=t_0\cdot \frac{b}{gcd\left(a,k\right)} \]
再进行调正:
\[ t=\left(t\%\frac{L}{d}+\frac{L}{d}\right)\%\frac{L}{d} \]

Code

#include <cstdio>
#include <iostream>
#define ll long long 
using namespace std;
ll x,y,m,n,l,t,k;
ll exgcd(ll a,ll b,ll &x,ll &y){
    if(b==0){
        x=1,y=0;
        return a;
    }
    int d=exgcd(b,a%b,x,y);
    int tmp=x;x=y;y=tmp-(a/b)*y;
    return d;
}
int main(){
    scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);
    ll a=n-m,b=x-y;
    if(a<0) a=-a,b=-b;//修正为正数 
    ll d=exgcd(a,l,t,k);
    if(b%d==0){
        t=t*b/d;//获得一个解
        t=(t%(l/d)+(l/d))%(l/d);//修正负数 
        printf("%lld",t);
    }else printf("Impossible");
    return 0;
}

转载于:https://www.cnblogs.com/saitoasuka/p/10338760.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值