【题目解析】汉中校区11/22周六晚比赛

~ 2025-11-30 19:21:45

A. 课间休息时间设置

分析

  • 难度:简单数学计算及按格式输出
  • 子任务 1(30 分):手动算算,44 个小时的课应该在 11 小时 5555 分时课间休息,所以课间休息时间应该是 09:55
  • 子任务 2(30 分):保证了时间是偶数,那去掉课间 1010 分钟之后剩下的部分也是偶数。两节课时间一样,都是 n102\frac{n - 10}{2} 分钟,也就是 (n-10)/2/60 小时 (n-10)/2%60 分钟。应该 (n-10)/2/60+8(n-10)/2%60 分下课。按格式输出即可。
  • 子任务 3(40 分):如果时间是奇数,实际上因为需要第一节课时间稍短一点,所以就按照子任务 2 的式子也是对的。

满分参考代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin >> n;
    n -= 10;
    n /= 2;

    int hh, mm;
    hh = 8 + n / 60;
    mm = n % 60;
    
    if (hh < 10)
        cout << "0";
    cout << hh;
    cout << ":";
    if (mm < 10)
        cout << "0";
    cout << mm;
    return 0;
}

B. 游泳同步起步

分析

  • 难度:简单枚举。
  • 子任务 1(30 分):因为 a=1a = 1,所以此时保证了每个整数时间 33DAI 都在起点。就看 kitten 经过了几次起点即可。显然 kitten 会在 0,b,2b,3b...0, b, 2b, 3b... 时间在起点,一共 nb+1\lfloor \frac{n}{b} \rfloor + 1 次。
  • 子任务 2(30 分):因为 bbaa 的倍数,所以显然 kitten 在起点时,33DAI 都在起点,还是一样输出 n/b+1 即可。
  • 子任务 3(40 分)
    • (做法 1)枚举:直接显然时间从 0n0 \sim n,如果当前时间 ii 除以 aa 的余数为 00 的话 33DAI 就在起点,除以 bb 的余数为 00 的话 kitten 就在起点。枚举每个时间,检查多少个时间满足这个要求即可。
    • (做法 2)数论:显然核心就是找 0n0 \sim n 有多少个 a,ba, b 的公倍数。因此可以找到最小公倍数 lcm(a,b),答案就是 n/lcm(a,b)+1。这个做法可以做更大数据范围。

满分参考代码

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

C. 比大小 Plus

分析

  • 难度:简单字符串操作。
  • 子任务 1(30 分):直接输入两个整数比较即可,多余的前导 00 是不会影响正常的整数输入的。
  • 子任务 2(30 分):没有多余前导 00 时,直接先比较长度,长度一致时直接用小于号比较两个 string 的字典序即可。
  • 子任务 3(40 分):先找到两个数第一个不是 0 的位置,然后比较长度,长度一致时比较字典序即可。

满分参考代码

#include <bits/stdc++.h>
using namespace std;
string a, b;
int aL, aLen;
int bL, bLen;
int main()
{
    cin >> a >> b;
    aL = 0;
    while (aL < (int)a.size() - 1 && a[aL] == '0')
        aL++;
    bL = 0;
    while (bL < (int)b.size() - 1 && b[bL] == '0')
        bL++;
    aLen = (int)a.size() - aL + 1;
    bLen = (int)b.size() - bL + 1;
    if (aLen > bLen)
    {
        cout << "first";
        return 0;
    }
    if (bLen > aLen)
    {
        cout << "second";
        return 0;
    }
    for (int i = aL, j = bL; i < a.size(); i++, j++)
    {
        if (a[i] > b[j])
        {
            cout << "first";
            return 0;
        }
        if (b[j] > a[i])
        {
            cout << "second";
            return 0;
        }
    }
    cout << "same";
    return 0;
}

D. 小数独验证

分析

  • 难度:二维数组。
  • 子任务 1(1 分):输出 yes 即可。只是为了提醒大家要注意读题。
  • 子任务 2(99 分):难点只是麻烦,可以把检查四个数是不是 1,2,3,41, 2, 3, 4 的排列打包成一个函数来简化代码。

满分参考代码

#include <bits/stdc++.h>
using namespace std;
int num[5];
bool check()
{
    sort(num + 1, num + 5);
    for (int i = 1; i <= 4; i++)
        if (num[i] != i)
            return false;
    return true;
}
int a[5][5];
int main()
{
    for (int i = 1; i <= 4; i++)
        for (int j = 1; j <= 4; j++)
            cin >> a[i][j];
    for (int i = 1; i <= 4; i++)
    {
        for (int j = 1; j <= 4; j++)
            num[j] = a[i][j];
        if (!check())
        {
            cout << "no\n";
            return 0;
        }
        for (int j = 1; j <= 4; j++)
            num[j] = a[j][i];
        if (!check())
        {
            cout << "no\n";
            return 0;
        }
    }
    // 左上
    num[1] = a[1][1], num[2] = a[1][2];
    num[3] = a[2][1], num[4] = a[2][2];
    if (!check())
    {
        cout << "no\n";
        return 0;
    }
    // 右上
    num[1] = a[1][3], num[2] = a[1][4];
    num[3] = a[2][3], num[4] = a[2][4];
    if (!check())
    {
        cout << "no\n";
        return 0;
    }
    // 左下
    num[1] = a[3][1], num[2] = a[3][2];
    num[3] = a[4][1], num[4] = a[4][2];
    if (!check())
    {
        cout << "no\n";
        return 0;
    }
    // 右下
    num[1] = a[3][3], num[2] = a[3][4];
    num[3] = a[4][3], num[4] = a[4][4];
    if (!check())
    {
        cout << "no\n";
        return 0;
    }
    cout << "yes\n";
    return 0;
}


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