
LCM Walk (HDU - 5584,简单数论)
发布日期:2021-05-04 06:49:49
浏览次数:29
分类:精选文章
本文共 1170 字,大约阅读时间需要 3 分钟。
一.题目链接
二.题目大意:
frog 从 (sx, sy) 出发.
每次可以从 (x, y) 走到 (x + lcm(x, y), y) 或 (x, y + lcm(x, y)).
现给出终点 (ex, ey),求可能起点的个数.
三.分析:
结论:
路径唯一
证明:
因此:如果 x > y,则
; x < y 时同理.
所以当前的点唯一确定上一步的点.
所以路径唯一.
由上述证明可知上一个点唯一,现逆推上一个点的坐标.
假设当前点为 (x, y),设 k == gcd(x, y)
则 x == nk, y == mk, 其中,gcd(n, m) == 1.
则 lcm(x, y) == xy / gcd == nk * mk / k == nmk.
若下一步增加 x,则坐标变为 (x + lcm(x, y), y)
即 (nk + nmk, mk) == ((m + 1)nk, mk),其中,gcd((m + 1)n, m) == 1.
所以,gcd(x + lcm(x, y), y) == gcd(x, y) == k.
所以
若 x > y,设 x == (m + 1)nk, y == mk
则,上一个点的坐标为
(nk, mk)
== (x / (m + 1), y)
== (x / (y / k + 1), y)
现讨论结束条件
若存在前一个点 (nk, mk),则当前点为 ((m + 1)nk, mk) == ((mk + k)n, mk) == ((y + k)n, mk)
所以当前 x 应为 y + k 的整数倍.
四.代码实现:
#includeusing namespace std;int gcd(int a, int b){ return b ? gcd(b, a % b) : a;}int main(){ int T; scanf("%d", &T); for(int ca = 1; ca <= T; ++ca) { int x, y, p; scanf("%d %d", &x, &y); if(x < y) swap(x, y); int cnt = 1, k = gcd(x, y); while(x % (y + k) == 0) { cnt++; x = x / (y / k + 1); if(x < y) swap(x, y); } printf("Case #%d: %d\n", ca, cnt); } return 0;}
发表评论
最新留言
不错!
[***.144.177.141]2025年04月03日 14时50分48秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
为什么讨厌所谓仿生AI的说法
2021-05-08
ORACLE 客户端工具
2021-05-08
基于LabVIEW的入门指南
2021-05-08
weblogic之cve-2015-4852
2021-05-08
Java注释
2021-05-08
C++ 函数重载
2021-05-08
.NET微信网页开发之使用微信JS-SDK调用微信扫一扫功能
2021-05-08
使用mybatis-generator生成底层
2021-05-08
Mybatis【5】-- Mybatis多种增删改查那些你会了么?
2021-05-08
计算输入的一句英文语句中单词数
2021-05-08
lvs+keepalive构建高可用集群
2021-05-08
6 个 Linux 运维典型问题
2021-05-08
取消vim打开文件全是黄色方法
2021-05-08
一个系统部署多个tomcat实例
2021-05-08
HP服务器设置iLO
2021-05-08
从头实现一个WPF条形图
2021-05-08
使用QT实现一个简单的登陆对话框(纯代码实现C++)
2021-05-08
QT :warning LNK4042: 对象被多次指定;已忽略多余的指定
2021-05-08
GLFW 源码 下载-编译-使用/GLAD配置
2021-05-08