两个闹钟
两个闹钟
有两个闹钟。
第一个闹钟会在 时刻响铃。
第二个闹钟会在 时刻响铃。
请计算两个闹钟第一次同时响铃的具体时刻。
输入格式
第一行包含两个整数 。
第二行包含两个整数 。
输出格式
一个整数,表示第一次同时响铃的具体时刻。
如果永远都不可能同时响铃,则输出 。
数据范围
所有测试点满足 。
输入样例1:
20 2 9 19
输出样例1:
82
输入样例2:
2 1 16 12
输出样例2:
-1
解题思路
我们是直接枚举答案。假设有,那么一定满足,同时还要满足。
我们的一开始的取值就要比和都要大。
然后,我们要满足,我们只用关心除以的余数是多少,可以发现除以的余数没有改变,不会影响余数。同理也不会影响余数。因此,我们从将和同时减去和的最小公倍数,也不会改变余数,,因此我们只需要考虑和在以内的数就可以了。因为如果大于的话,那么我们就减去,并不会影响余数。因为和的值在以内,所以最小公倍数在以内。又因为和最大是,因此枚举到就可以了。
AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 int main() { 6 int a, b, c, d; 7 scanf("%d %d %d %d", &a, &b, &c, &d); 8 9 for (int i = max(b ,d); i <= 10100; i++) { 10 if ((i - b) % a == 0 && (i - d) % c == 0) { 11 printf("%d", i); 12 return 0; 13 } 14 } 15 16 printf("-1"); 17 18 return 0; 19 }
还可以用扩展欧几里得。由,得到。如果,才有解。先让取到最小正整数,然后通过式子求得,当,那么和同时加上对应的值。
AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 int exgcd(int a, int b, int &x, int &y) { 6 if (b == 0) { 7 x = 1, y = 0; 8 return a; 9 } 10 11 int d = exgcd(b, a % b, y, x); 12 y -= a / b * x; 13 14 return d; 15 } 16 17 int main() { 18 int a, b, c, d, x, y; 19 scanf("%d %d %d %d", &a, &b, &c, &d); 20 21 int gcd = exgcd(a, c, x, y); 22 if ((d - b) % gcd) { 23 printf("-1"); 24 } 25 else { 26 x *= (d - b) / gcd; 27 int tx = c / gcd, ty = a / gcd; 28 x = (x % tx + tx) % tx; 29 y = (b + a * x - d) / c; 30 while (y < 0) { 31 x += tx; 32 y += ty; 33 } 34 35 printf("%d", b + a * x); 36 } 37 38 return 0; 39 }
参考资料
AcWing 4379. 两个闹钟(AcWing杯 - 全国联赛):https://www.acwing.com/video/3755/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16074352.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效