1/17日周六晚比赛题解

~ 2026-1-24 9:50:32

[A.起床时间]

[分析]

  • 难度:简单数学题
  • 子任务 1(30 分):由于 xMx≤M,所以直接输出 hhmxm−x 就好。
  • 子任务 2(30 分):由于是刚好减去一个小时,所以直接输出 h1h−1mm 就好。
  • 子任务 3(40 分):有多种做法。
    • 做法 1:可以直接模拟时间变化,先把分钟数 mm 减去 xx,然后只要分钟数小于 00,就给小时数减少 11,分钟数加上 6060。由于 x120x≤120,所以这个过程最多执行两次就可以,重复两次 if 语句判断即可。
    • 做法 2:我自己的习惯是先把“小时:分钟”的时间描述法转换为只有分钟的,即“小时数 ×60+ 分钟数” 这么多分钟。这样在同一天内就可以直接减去 xx,再转回去即可。

[满分参考代码]

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int h, m, x;
    cin >> h >> m >> x;
    int ans = h * 60 + m - x;
    cout << ans / 60 << " " << ans % 60 << "\n";
    return 0;
}

[B.联合 ChatGPT]

[分析]

  • 难度:简单的条件判断与求和
  • 子任务 1(30 分):因为只有一道题,所以直接输出 a1,b1a1,b1 中的较大值就好。
  • 子任务 2(30 分):因为保证了 aibiai≤bi 所以直接输出所有 bibi 之和就好,简单的循环输入与求和。
  • 子任务 3(40 分):在子任务 2 的基础上,加上判断 ai,biai,bi 哪个高算哪个就好。需要最后的答案可以达到 100×109100×109 是超过了 int 的,需要使用 long long

[满分参考代码]

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n, a, b;
    cin >> n;
    long long ans = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> a >> b;
        ans += max(a, b);
    }
    cout << ans << "\n";
    return 0;
}

[C.摩斯电码数数]

[分析]

  • 难度:简单的字符串枚举,主要给大家提醒了一下转义符的使用。
  • 子任务 1(30 分):因为保证了不包含 \ 所以只有一个单词,只需要输出 11 即可。
  • 子任务 2(30 分):因为保证了编码长度为 55,所以答案就是 (s.size()+1)/6
  • 子任务 3(40 分):单词数就是 \ 数量加一。记住反斜杠本身也是个特殊字符,需要用转义模式 '\\' 表示即可。

[满分参考代码]

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    int ans = 0;
    cin >> s;
    for (int i = 0; i < s.size(); i++)
        if (s[i] == '\\')
            ans++;
    cout << ans + 1 << "\n";
    return 0;
}

[D.校门外好多树]

[分析]

  • 难度:数组综合应用。
  • 子任务 1(30 分):因为 x=1x=1,所以在完成了基础的暴力枚举标记所有有数的位置后,就是一个弱化版的“最长平台”问题,有几段树答案就是几。统计多少个位置有树且前一个位置没树即可(第一个位置特殊判断)。
  • 子任务 2(30 分):每次不再是区间修改而是单点修改了。给没学过循环嵌套的同学送点分,但其实意义不大。
  • 子任务 3(40 分):如果是数据范围更大,就需要使用差分的方式处理。但是数据范围这么小,直接暴力标记每个位置有没有树即可。标记完后,问题就变成了判断有几段树的数量达到了 xx

[满分参考代码]

#include <bits/stdc++.h>
using namespace std;
int L, M, x;
bool a[5005];
int main()
{
    cin >> L >> M >> x;
    // 一开始认为所有位置都有树
    for (int i = 0; i <= L; i++)
        a[i] = true;
    // 把建地铁的位置的树都拔掉
    for (int i = 1; i <= M; i++)
    {
        int l, r;
        cin >> l >> r;
        for (int j = l; j <= r; j++)
            a[j] = false;
    }
    // 从前往后,找整段的树
    int now = 0; // 当前段的树的棵数
    int ans = 0; // 记录有几段树的长度达到了 x
    for (int i = 0; i <= L; i++)
    {
        if (a[i] == true)
            now++;
        else
        {
            if (now >= x)
                ans++;
            now = 0;
        }
    }
    // 有可能出现一段树,需要特殊处理
    if (now >= x)
        ans++;
    cout << ans << "\n";
    return 0;
}


我们会审查剪贴板内容,并对发布不合适内容的同学进行相应的处理