跳转至

语法周赛round25

T1

知识点:顺序语句

代码
int type, A, B, C, D;
cin >> type >> A >> B >> C >> D;
if (type == 0)
    cout << A + B;
else
    cout << max(A - C, 0) + max(B - D, 0);

T2

知识点:条件判断。

代码
int A, B, C, K;
cin >> A >> B >> C >> K;
if (A + B >= K)
    cout << "Yes\n";
else
    cout << "No\n";
if (___)
    cout << "Yes\n";
else
    cout << "No\n";
if (___)
    cout << "___";
else
    cout << "___"; // 在下划线处填空吧!

T3

知识点:字符处理,循环。

本题的输入格式特殊:三个整数之间由字符 / 分隔,而不是常见的空格或换行,因此不能直接使用

cin >> k >> d >> a;

来读入数据。

可以借助一个字符变量来“吸收”分隔符 /,例如:

char x;
cin >> k >> x >> d >> x >> a;

读取完成后,只需根据题意,对每名战士计算其对应的实力值,并在遍历过程中记录“当前最大实力”及其编号。最后输出最大值的编号即可。

代码
for (int i = 1; i <= n; i++)
{
    int k, d, a;
    char x;
    cin >> k >> x >> d >> x >> a;
    int sum = 0; // 记录实力值
    if (k - d >= 10)
        sum = k * (k - d) + a;
    else if (k >= d)
        sum = (k - d + 1) * 3 + a;
    else
        sum = a * 2;
    if (sum > mx)
    {
        mx = sum;
        pos = i; // 记录最大值的编号
    }
}

T4

知识点:数组,循环嵌套。

题目分析

给定 $n$ 个宝宝及其上进心 $a_1, a_2, \ldots, a_n$, 年龄为 $n$ 的宝宝一定是好宝宝; 其他宝宝只有当其上进心严格大于所有年龄比它大的宝宝的上进心时,才是好宝宝。


解题思路

  • 对于每个宝宝 $i$($1 \leq i \leq n-1$), 遍历所有年龄比它大的宝宝(即 $j > i$), 判断 $a_i$ 是否严格大于所有这些 $a_j$;
  • 如果满足,计数器加 $1$;
  • 年龄为 $n$ 的宝宝直接计入计数器。

实现步骤

  • 外层循环遍历 $i$,for (int i = 1; i < n; i++) 无需遍历到 $n$,第 $n$ 个一定是好宝宝;
  • 使用标记变量打标记,初始化 ok 设为 $1$;
  • 内层循环遍历 $j$,for (int j = i + 1; j <= n; j++)。遍历年龄更大的宝宝。
  • 若存在 a[i] <= a[j],说明上进心低于年龄更大的。此时更新 ok 为 $0$。
  • 根据内层循环结束后 ok 的值来进行计数即可。
代码
int ans = 1;
for (int i = 1; i < n; i++)
{
    int ok = 1;
    for (int j = i + 1; j <= n; j++)
        if (a[i] <= a[j])
            ok = 0;
    if (ok)
        ans++;
}

T5

知识点:数组,循环嵌套。

题目分析

  • 有 $m$ 棵树和 $m-1$ 片草坪,排列为:树 $1$,草坪 $1$,树 $2$,草坪 $2$,$\ldots$,树$m$;
  • 两种施工操作破坏区间内的绿化:
    • 类型 $1$:破坏第 $l$ 棵树和第 $r$ 棵树之间(不含 $l,r$)的所有绿化,即破坏树 $(l+1)$ 到 $(r-1)$ 和草坪 $l$ 到 $r-1$;
    • 类型 $2$:破坏第 $l$ 棵树和第 $r$ 棵树之间(包含 $l,r$)的所有绿化,即破坏树 $l$ 到 $r$ 和草坪 $l$ 到 $r-1$;
  • 施工后统计剩余未被破坏的树和草坪数量。

解题思路

  • 维护两个数组:
    • tree[1,.., m] 标记每棵树是否被破坏(0 表示存活,1 表示被破坏);
    • grass[1,.., m - 1] 标记每片草坪是否被破坏;
    • 两个数组初始化均设为全局变量即可。
  • 对每次施工,根据类型更新 treegrass 的状态;
  • 最后分别统计两个数字里 0 的个数即为剩余的树和草坪数。

实现步骤

  • 初始化 treegrass 数组,全部标记为 0
  • 遍历每次施工:
    • 若类型为 $1$:
      • 对树:标记 tree[l + 1, .., r - 1]1(若区间非空);
      • 对草坪:标记 grass[l, .. ,r - 1]1
    • 若类型为 $2$:
      • 对树:标记 tree[l, .., r]1
      • 对草坪:标记 grass[l, .., r - 1]1
  • 统计 tree[1,.., m]0 的数量为剩余树数,统计 grass[1,.., m - 1]0 的数量为剩余草坪数;
  • 输出两个结果。

代码
cin >> m >> n;
for (int i = 1; i <= n; i++)
{
    int x, l, r;
    cin >> x >> l >> r;
    if (x == 1)
    {
        for (int j = l + 1; j <= r - 1; j++) 
            tree[j] = 1;
        for (int j = l; j <= r - 1; j++) 
            grass[j] = 1;
    }
    else
    {
        for (int j = l; j <= r; j++) 
            tree[j] = 1;
        for (int j = l; j <= r - 1; j++) 
            grass[j] = 1;
    }
}
for (int i = 1; i <= m; i++)
    if (tree[i] == 0)
        ans1++;
for (int i = 1; i < m; i++)
    if (grass[i] == 0)
        ans1++;
cout << ans1 << ' ' << ans2;