【ybt金牌导航8-6-1】【luogu P1516】青蛙约会 / 不定方程同余方程例题

青蛙约会

题目链接:ybt金牌导航8-6-1 / luogu P1516

题目大意

有两个东西在环上各自的位置往同一个方向跳,每次各会跳一定的距离。
然后问你要跳多少次,这两个东西才会在同一个地方。
如果不会在同一个地方,也要按题目要求输出表示。

思路

那我们考虑能不能列出方程。
s+mx=t+nx(mod L)
s,t 分别是两个东西出发的位置,m,n 是两个东西每次跳的格数。

化一下:(mn)x=ts(mod L)
这是一元线性同余方程,自然会想到把它变成二元一次不定方程,然后用扩展欧几里得来做。
(mn)x+Ly=ts

但是它要有解要有条件,就是 (mn)L 互质。
那如果不互质,就输出不可行,否则我们就继续做。

那你就把左边的两个变成互质:mngcd(mn,L)x+Lgcd(mn,L)y=tsgcd(mn,L)
(记得之后的模数也要除,因为你这里的 L 变成了 Lgcd(mn,L),它就表示模数)

但是扩展欧几里得是 ax+by=1,它的等式右边是 1 啊。
那简单,我们就把式子的右边看成 1,算出 x,然后再把右边乘回去,就可以了。

然后你就把它弄出来,就可以输出了。

代码

#include<cstdio> #define ll long long using namespace std; ll x, y, m, n, mo; ll X, Y, a, b, c; ll GCD(ll x, ll y) {//普通的求 gcd if (!y) return x; return GCD(y, x % y); } ll exgcd(ll a, ll &x, ll b, ll &y) {//扩展欧几里得求 ax+by=1 if (!b) { x = 1; y = 0; return a; } ll re = exgcd(b, y, a % b, x); y -= a / b * x; return re;//顺便可以求出 gcd,可用可不用 } int main() { scanf("%lld %lld %lld %lld %lld", &x, &y, &m, &n, &mo); //弄出一元线性同余方程,然后转成二元一次不定方程 a = (m - n + mo) % mo; b = mo; c = (y - x + mo) % mo; int gcd = GCD(a, b);//判断是否有解 if (c % gcd != 0) { printf("Impossible"); return 0; } a /= gcd;//把式子化成 ax+by=c 且 a,b 互质的形式 b /= gcd; c /= gcd; exgcd(a, X, b, Y); X = (X % mo + mo) % mo; printf("%lld", (X * c) % (mo / gcd));//算出答案(记得这里模数不是mo) return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/YBT_JPDH_8-6-1.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(20)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示