在算法竞赛的世界里,Codeforces 平台以其高质量的题目和激烈的竞争吸引着众多程序员。本文将聚焦于 Codeforces Round #704 (Div. 2) 中的 A 题,名为“Three Swimmers”(三名游泳者)。 尽管这道题目看似简单,实则蕴含着一些巧妙的逻辑思维。我们将从题目描述出发,逐步剖析解题思路,并提供一份清晰易懂的代码实现,帮助读者更好地理解和掌握此类问题的解题技巧。通过对本题的深入分析,希望能为广大算法爱好者提供一些有价值的参考,并在未来的编程实践中能够游刃有余地解决类似问题。 本博客将深入探讨这个问题的各个方面,旨在提供一个全面且易于理解的指南。无论您是算法竞赛的新手还是经验丰富的参与者,本文都将帮助您提高解决问题的能力。我们将详细解释题目要求,分析关键的解题思路,并提供清晰的代码示例。此外,我们还将讨论一些优化技巧,以确保您的解决方案既正确又高效。通过本文的学习,您将不仅掌握这道特定题目的解法,更重要的是,您将学会如何将类似的逻辑应用于其他编程挑战中。 在后续的内容中,我们将反复提及关键词,例如Codeforces,算法竞赛,游泳者问题,解题思路,代码实现,编程挑战等,以增加SEO关键词密度,确保更多用户能够通过搜索引擎找到这篇文章,获得有价值的帮助。
三名游泳者问题的关键要点
理解题目描述:清晰掌握游泳者运动规律
确定解题思路:找到等待时间的计算方法
代码实现:编写高效的代码逻辑
优化技巧:提升代码性能
特殊情况处理:考虑边界条件和临界情况
题目描述与分析
问题背景
三名游泳者决定在游泳池举办一个派对。在中午,他们从游泳池的左侧开始游泳。第一个游泳者完成整个游泳池的往返需要 a 分钟,第二个游泳者需要 b 分钟,第三个游泳者需要 c 分钟。因此,第一个游泳者将在 0, a, 2a, 3a 分钟后到达左侧,第二个游泳者将在 0, b, 2b, 3b 分钟后到达左侧,第三个游泳者将在 0, c, 2c, 3c 分钟后到达左侧。
你来到游泳池的左侧,恰好在他们开始游泳后 p 分钟。确定你必须等待多久(以分钟为单位),直到其中一名游泳者到达游泳池的左侧。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

输入 第一行包含一个整数 t (1 ≤ t ≤ 1000),表示测试用例的数量。接下来的 t 行包含测试用例的描述,每行一个。 每行包含四个整数 p, a, b 和 c (1 ≤ p, a, b, c ≤ 10^18),表示在你到达游泳池的时间以及游泳者完成整个游泳池的往返所需的时间。
输出 对于每个测试用例,输出一个整数,表示你必须等待多久(以分钟为单位),直到其中一名游泳者到达游泳池的左侧。
问题分析
这个问题实际上是一个求最小等待时间的问题。我们需要找到一个最小的非负整数 w,使得 p + w 是 a, b, c 中至少一个数的倍数。

换句话说,我们需要找到 a, b, c 各自的倍数中,大于等于 p 的最小值,然后取这些最小值中的最小值。这个最小值减去 p 就是我们要等待的时间。
关键点:
- 倍数: 游泳者到达左侧的时间是他们各自游泳时间的倍数。
- 等待时间: 我们需要找到一个等待时间,使得总时间是某个游泳者游泳时间的倍数。
- 最小: 我们需要找到的是最小的等待时间。
为了更好地理解,让我们考虑一个具体的例子:假设 p = 9, a = 5, b = 4, c = 8。这意味着你到达游泳池时已经过去了 9 分钟,三个游泳者分别需要 5, 4, 8 分钟完成一次往返。
- 第一个游泳者到达左侧的时间:0, 5, 10, 15, ...
- 第二个游泳者到达左侧的时间:0, 4, 8, 12, 16, ...
- 第三个游泳者到达左侧的时间:0, 8, 16, 24, ...
我们需要找到大于等于 9 的最小值:
- 对于第一个游泳者:10
- 对于第二个游泳者:12
- 对于第三个游泳者:16
这些最小值中的最小值是 10。因此,你需要等待 10 - 9 = 1 分钟。
从这个例子可以看出,核心的运算是找到大于等于 p 的最小倍数。这可以通过向上取整的方式实现。我们将 p 除以 a, b, c,然后向上取整,再乘以 a, b, c 得到各自的最小倍数。
在接下来的章节中,我们将详细介绍如何使用代码实现这个思路,并讨论一些优化技巧。
解题思路与步骤
解题步骤详解
要解决“三名游泳者”问题,我们需要设计一种算法来有效地计算最小等待时间。以下是详细的解题步骤:
-
输入处理:
-
读取测试用例的数量 t。

-
对于每个测试用例,读取四个整数 p, a, b, c。
-
-
特殊情况处理:
- 如果 p 是 a, b, c 中至少一个数的倍数,则等待时间为 0。
- 如果 p % a == 0 || p % b == 0 || p % c == 0,则输出 0 并继续下一个测试用例。
- 如果 p 是 a, b, c 中至少一个数的倍数,则等待时间为 0。
-
计算等待时间:
- 否则,我们需要计算 a, b, c 各自的倍数中,大于等于 p 的最小值。
- 计算 a 的最小倍数:next_a = ((p + a - 1) / a) * a; 这行代码核心在于向上取整的技巧。
p + a - 1确保了如果 p 不是 a 的整数倍,那么结果至少会增加 a,从而实现向上取整。然后除以 a 并乘以 a,就得到了大于等于 p 的最小的 a 的倍数。 - 计算 b 的最小倍数:next_b = ((p + b - 1) / b) * b;
- 计算 c 的最小倍数:next_c = ((p + c - 1) / c) * c;
- 计算 a 的最小倍数:next_a = ((p + a - 1) / a) * a; 这行代码核心在于向上取整的技巧。
- 否则,我们需要计算 a, b, c 各自的倍数中,大于等于 p 的最小值。
-
找到最小等待时间:
- 计算等待时间:wait_a = next_a - p, wait_b = next_b - p, wait_c = next_c - p。
- 找到最小等待时间:ans = min(wait_a, min(wait_b, wait_c)); 这里使用了
min函数来找到三个等待时间中的最小值。这意味着我们将选择最快到达左侧的游泳者。
-
输出结果:
- 输出最小等待时间 ans。
这个算法的核心在于向上取整的技巧以及找到三个值中的最小值。通过这种方式,我们可以高效地计算出最小的等待时间。
SEO优化提示: 在编写代码注释时,务必使用关键词,例如“最小倍数”、“向上取整”、“最小等待时间”等。这有助于搜索引擎更好地理解代码的功能,并提高代码的可搜索性。
以下markdown表格展示了一些示例数据以及对应的结果分析,希望能帮助你更好地理解上述步骤:
| p | a | b | c | next t_a | next t_b | next t_c | wait t_a | wait t_b | wait t_c | ans | 说明 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 9 | 5 | 4 | 8 | 10 | 12 | 16 | 1 | 3 | 7 | 1 | 计算各自的最小倍数 (>= p),然后取最小值。 |
| 10 | 5 | 4 | 8 | 10 | 12 | 16 | 0 | 2 | 6 | 0 | 因为 10 是 5 的倍数,所以等待时间为 0。 |
| 7 | 3 | 6 | 9 | 9 | 6 | 9 | 2 | -1 | 2 | -1 | 注意:这里出现负数因为6能整除7,返回0 |
| 4 | 4 | 5 | 6 | 4 | 5 | 6 | 0 | 1 | 2 | 0 | 因为4能整除4,返回0 |
代码实现与优化
以下是用 C++ 实现的代码,它展示了如何高效地解决“三名游泳者”问题。这段代码简洁易懂,并且经过了优化,能够处理大数据量。










