POJ 1061 青蛙的约会
题意:有两只青蛙,在L那么长的环上,起点分别为x, y,一次跳跃的长度分别为m,n,问几次跳跃后他们能相遇,如不能相遇输出"Impossible"。
解法:同余问题+扩展欧几里得。从题意容易推出以下式子:
设跳跃次数为t,mt + x ≡ nt + y (mod L) (1)。
根据同余的性质:当a ≡ b (mod c)时,(a - b) % c = 0。
则式(1)转化成(m - n)t + x - y = pL(p ∈ N)。
问题变为解二元一次方程ax + by = c最小可行解问题。
解决这类问题的算法是扩展欧几里得算法:对于不完全为0的非负整数a,b,gcd(a, b)表示a,b的最大公约数,必然存在整数对x,y,使得gcd(a,b) = ax + by。
对于本题当c不能整除gcd(a, b)的时候说明无解,应输出"Impossible"。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int exgcd(LL a, LL b, LL &x, LL &y) { if (b == 0) { x = 1; y = 0; return a; } int r = exgcd(b, a % b, x, y); int t = x; x = y; y = t - a / b * y; return r; } |
证明:当b = 0时,gcd(a, b) = a,所以x = 1, y = 0。当b <> 0时,ax + by = gcd(a, b),根据欧几里得算法(辗转相除法),令a = b, b = a % b,则新等式为bx1 + (a - [a / b] * b)y1 = gcd(b, a % b),整理得ay1 + b(x1 - [a / b]y1) = gcd(b, a % b),因为gcd(a, b) = gcd(b, a % b),所以x = y1, y = x1 - [a / b] * y1,通过递归实现。(参考自百度百科)
当c能整除gcd(a, b)时,通过扩展欧几里得算法求出ax + by = gcd(a, b)的解X时,ax + by = c的最小解则为X * (c / gcd(a, b)),由于X可能为负数,所以最终答案应为(X % gcd(a, b) + gcd(a, b)) % gcd(a, b)。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; LL exgcd(LL a, LL b, LL &x, LL &y) { if (b == 0) { x = 1; y = 0; return a; } LL r = exgcd(b, a % b, x, y); LL t = x; x = y; y = t - a / b * y; return r; } int main() { LL x, y, m, n, l; while (~ scanf ( "%lld%lld%lld%lld%lld" , &x, &y, &m, &n, &l)) { LL X, Y; LL a = n - m, b = l, c = x - y; LL r = exgcd(a, b, X, Y); if (c % r != 0) { puts ( "Impossible" ); continue ; } X *= c / r; LL R = b / r; LL ans = (X % R + R) % R; cout << ans << endl; } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· SQL Server 内存占用高分析
· 盘点!HelloGitHub 年度热门开源项目
· DeepSeek V3 两周使用总结
· 02现代计算机视觉入门之:什么是视频
· C#使用yield关键字提升迭代性能与效率
· 回顾我的软件开发经历(1)