[语言月赛 202509] 朱猪时刻 的题解


记住只在没有思路时使用题解,不要从它复制粘贴代码。请尊重题目和题解的作者。
在解题之前提交题解的代码会导致封禁。

作者: admin

概述

本题要求根据一个给定的 24 小时制时刻,算出距离下一个“朱猪时刻”(分钟数除以 5 的余数为 3 的时刻)还有多少分钟。核心在于小时数完全不参与运算,答案只由分钟数模 5 的余数决定,为 (3 - (m \bmod 5)) \bmod 5。

分析
核心观察

只有分钟数模 5 的余数会影响答案。因为 60 是 5 的倍数,把小时折算成分钟再加到分钟数上不会改变这个余数,所以“小时内的分钟数”与“一天中的第几分钟”模 5 同余,两种理解的结论完全一致。

思路

设当前分钟数为 m,记 r = m \bmod 5。

朱猪时刻的分钟数 m' 满足 m' \bmod 5 = 3。时间只会向后推进,因此要找的是最小的非负整数 d,使 (m + d) \bmod 5 = 3。两边同时取模 5 得 (r + d) \bmod 5 = 3,于是

\displaystyle  d = (3 - r) \bmod 5, \quad d \in \{0, 1, 2, 3, 4\}

即

\displaystyle  d = (3 - (m \bmod 5)) \bmod 5

当 r = 3 时 d = 0,正对应题面中“如果它就是一个朱猪时刻,输出 0”的情形。由于 d \le 4,等待过程中分钟数至多前进 4 分钟,绝不会跨过一整小时,时针与日期都不会变化,所以小时数不需要出现在计算里。

朴素做法是从当前时刻出发逐分钟向后枚举,检查每个分钟数模 5 是否为 3。由于最多枚举 4 次就能命中,这种做法同样可以通过,只是判断逻辑比直接求余数差更长。

具体示例

样例 1 给出 08 15:分钟数 15 \bmod 5 = 0,答案 (3 - 0) \bmod 5 = 3,等待 3 分钟后到达 08:18,与输出一致。

样例 2 给出 18 43:分钟数 43 \bmod 5 = 3,答案 (3 - 3) \bmod 5 = 0,说明当前时刻本身就是朱猪时刻,不需要等待。

样例 4 给出 13 41:分钟数 41 \bmod 5 = 1,答案 (3 - 1) \bmod 5 = 2,与输出一致。

算法步骤
  1. 读入小时数 h 与分钟数 m。
  2. 计算 ans 为 (3 - (m \bmod 5) + 5) \bmod 5,即先取分钟数除以 5 的余数,再算出它距离余数 3 还差多少分钟,最后对 5 取余,把结果落在 0 \sim 4 内。
  3. 输出 ans。
复杂度分析
  • 时间:只做一次读入与常数次取余运算,为 O(1)。
  • 空间:只保存常数个整型变量,为 O(1)。
实现注意事项
  • 小时数只是输入的一部分,不参与任何运算;题面给出的 07:00 \sim 22:30 范围仅用于保证时刻合法,无需用它做特判。
  • C++ 中负数取模的结果仍可能为负(m \bmod 5 = 4 时 3 - 4 = -1),因此要写成 (3 - m \% 5 + 5) \% 5 先补齐再取模。
  • Python 的 % 结果恒为非负,(3 - m \% 5) \% 5 可以直接使用,不需要手动加 5。
  • 原题解代码写成 (8 - m % 5) % 5,由于 8 \equiv 3 \pmod 5,它与 (3 - m \% 5) \% 5 恒等(样例 1 的 08 15 在两式下都得 3);这里写成 3 更贴合“余数为 3”的定义,便于核对。
  • 输入的两个数用空格分隔而非冒号,按两个整数读入即可;分钟数是第二个整数,小时数读到后丢弃。
  • 当前时刻已经是朱猪时刻时输出 0,公式在 m \bmod 5 = 3 时自然给出 0,不需要额外分支。
  • 答案的取值范围是 0 \sim 4,用 int 即可,不必担心溢出。
  • 输出只有一个整数,行末换行不影响判题。
源代码
#include <cstdio>

int main() {
    int h = 0, m = 0;
    if (std::scanf("%d %d", &h, &m) != 2) return 0;
    // 60 是 5 的倍数,故一天中的分钟数与小时内分钟数模 5 同余,小时数不参与计算
    const int ans = (3 - m % 5 + 5) % 5;
    std::printf("%d\n", ans);
    return 0;
}
import sys


def main():
    data = sys.stdin.read().split()
    m = int(data[1])
    # 60 是 5 的倍数,故一天中的分钟数与小时内分钟数模 5 同余,小时数不参与计算
    print((3 - m % 5) % 5)


if __name__ == "__main__":
    main()

评论

目前没有评论。