跳转至

语法周赛round15

T1 你几岁了

本题考查基本的输入输出语句。注意输出格式即可。

  • 使用 count 实现:cout << "I am " << x << " years old.";
  • 使用 printf 实现:printf("I am %d years old.", x);

T2 大小比较

本题考查条件判断语句。if - else 的使用。

注意数据范围 $a,b\leq 10^5$ 因此使用 int 变量即可。

注意输出单词的大小写问题。


T3 求和

本题考查求和运算和数学求和公式的使用。

首先 $n\leq 10^7$,那么计算器自己算一下 $1+2+\ldots+10^7=\dfrac{(1+10^7)\times 10^7}{2}$ 肯定是超过了 int 的。

因此建议变量均设为 long long 类型,

long long n;
cin >> n;
for (int i = 1; i <= n; i++) {
    // (首项 + 末项) * 项数 / 2
    long long sum = (1 + i) * i / 2;
}

T4 数组调整

本题考察数组的基本使用。

  • 根据数据范围 $n\leq 10^6$,因此数组大小需要定义为 1000005

  • 根据数据范围 $a_i\leq 10^9$,数据的元素类型用 int 即可。

因此首先定义 int a[1000005] 这样的数组。注意定义为全局变量。

题目要求修改第 $k$ 个数字,则执行 a[k] = -a[k] 即可。最后重新遍历整个数组的元素求和即可。

注意求和变量需要使用 long long

// 输入代码略
a[k] = -a[k];
long long sum = 0;
for (int i = 1; i <= n; i++)
{
    sum += a[i];
}
cout << sum;

T5 渡荆门送别

本题主要考查数组的使用以及最大值最小值的求解。

  • 根据数据范围 $n\leq 10^6$,因此数组大小需要定义为 1000005

  • 根据数据范围 $a_i\leq 10^{18}$,数据的元素类型用 long long 即可。

因此首先定义 long long a[1000005] 这样的数组。注意定义为全局变量。

求解最大值和求最小值的步骤基本类似:

  • 最大值:初始化一个较小的变量,按照本题的范围需要定义 long long mx = 0。(由于 $a_i\geq 0$ 因此不可能比 $0$ 还小。)
  • 最小值:初始化一个较大的变量,按照本题的范围需要定义 long long mn = 1e18。(由于 $a_i\leq 10^{18}$)

    • aeb 的作用就是 $a\times 10^b$,其结果为 double 类型。
    • 因此 1e18 就是 10^{18}
  • a[i] > mx 时,更新 mx

  • a[i] < mn 时,更新 mn
for (int i = 1; i <= n; i++)
{
    cin >> a[i];
    if (a[i] > mx)
    {
        mx = a[i];
    }
    if (a[i] < mn)
    {
        mn = a[i];
    }
}

接下来题目求解每个数字和最大值,最小值分别差多少。那么遍历数组两次分别求解即可。

for (int i = 1; i <= n; i++)
{
    cout << mx - a[i] << " ";
}
cout << endl;
for (int i = 1; i <= n; i++)
{
    cout << a[i] - mn << " ";
}

T6 俊俏地鼠的远亲

这道题的目标是:对于给定的 $n\times m$ 个地鼠窟,每个窟里有一只地鼠和他的 身份标识。我们需要给出每个窟里地鼠与其他相同身份标识的地鼠之间最远的方块距离。

如果没有其他这种身份标识的地鼠,那就输出 $0$。

第一步:输入数据

  • 从标准输入读入 $n$ 行 $m$ 列
  • 将每个窟里地鼠的标识值 a[i][j] 存入二维数组

第二步:找远亲

  • 遍历所有地鼠窟 $(i, j)$

    • 再遍历全地图所有其他地鼠 $(k, l)$
    • 如果 a[i][j] == a[k][l],表示是亲戚

      • 计算距离 $dis=(i - k)^2 + (j - l)^2$
      • 记录最大值,用一个新数组更新答案 b[i][j] = max(b[i][j], dis)
for (int i = 1; i <= n; i++)
{
    for (int j = 1; j <= m; j++)
    {
        for (int k = 1; k <= n; k++)
        {
            for (int l = 1; l <= m; l++)
            {
                if (a[i][j] == a[k][l])
                {
                    b[i][j] = max(b[i][j], (i - k) * (i - k) + (j - l) * (j - l));
                }
            }
        }
    }
}
for (int i = 1; i <= n; i++)
{
    for (int j = 1; j <= m; j++)
    {
        cout << b[i][j] << " ";
    }
    cout << "\n";
}

T7 影子字符串

本题用 map<string, int> 去做是最简单的。可以自己学一下 map 的用法。

点我学习 map

map<string, bool> vis; 
// 给字符串打标记 
while (true)
{
    string s;
    cin >> s;
    if (s == "0") break;
    if (vis.count(s)) // 说明已经有 s 
    {
        continue; 
    } 
    cout << s;
    vis[s] = 1; // 打标记 
}

T8 天天爱跑步

我们要模拟一个签到的过程,每一天:

  • 看看有没有签到(输入是 $1$ 表示 ,$0$ 表示 没有);
  • 如果有,就根据 连续签到的天数 决定今天拿多少奖励;
  • 把这个奖励累加到总的活跃值里。

解题步骤

我们使用两个变量:

  • day:表示当前连续签到的天数;
  • sum:表示活跃值的总和。

处理流程:

  • 如果签到(输入是 $1$):
    • day += 1
    • 根据 day 判断当前奖励值是多少
    • 奖励累加到 sum
  • 如果未签到(输入是 $0$):
    • day = 0
    • 奖励为 $0$,不增加总值
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int v1, v3, v7, v30, v120, v365;
    cin >> v1 >> v3 >> v7 >> v30 >> v120 >> v365;

    int day = 0, sum = 0;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;

        if (x == 0) {
            day = 0;
            continue;
        }

        day += 1;
        if (day < 3)
            sum += v1;
        else if (day < 7)
            sum += v3;
        else if (day < 30)
            sum += v7;
        else if (day < 120)
            sum += v30;
        else if (day < 365)
            sum += v120;
        else
            sum += v365;
    }

    cout << sum;
    return 0;
}