LGOI 2023 游记

发布时间 2023-06-04 21:56:56作者: laialaodi

前言

比赛是深圳市龙岗区的小学生信息学奥林匹克竞赛,下面讲题时会概括题目,要原题的找我。

说真的,没想到疫情三年后的第一场比赛就这么水。

1. 篮球赛比分

给你一场篮球比赛的得分情况,如 A1B3A2B1A3B3B1# 表示 A 队分别得到了 1 分、2 分、3 分,共 6 分,B 队分别得到了 3 分、1 分、3 分、1 分,共 8 分。每条记录以 # 结束。输出 A 队和 B 队的得分,用一个空格分隔开。

用 2 个变量分别计算 AB 队的得分,模拟一下完事。

2. 重复出现的整数的个数

给你一些不超过 \(1000\) 的正整数,找出重复出现的整数个数。

首先看到数据规模不大于 \(1000\) 就很容易想到,用一个 \(1001\) 项的数组存放每一个数字出现的次数(如a [100] 代表 100 出现的次数),最后输出时判断次数大于 \(1\)(重复)时输出垓数。

3. 圆环上的数的和

小龙把 \(n\) 个数放在一个圆环上(首尾相连),现给定 \(m\),求圆环上连续 \(m\) 个数最大的和。

虽然题目说得天花乱坠,但是我们可以发现,题目实际上是让我们对圆环的所有可能的连续的 \(m\) 个数的和求最大值。

4. 蛙跳

青蛙一次能跳 \(1 \sim 3\) 个方格,请问它跳到第 \(n\) 个方格有几种跳法?

设到达方格 \(i\) 的跳法有 \(S_i\) ,由于要到达方格 \(i\) 只能从 \(i\) 的前面 \(3\) 个方格过来,所以 \(S_i = S_{i-1} + S_{i-2} + S_{i-3}\)

思路有了,下面开始解题。

递归法

我们可以定义一个函数,用于计算 \(S_i\) ,记得设置递归终止条件!

int calc(int i)
{
    if (i <= 2)
    {
        return 1;
    }
    else if (i == 3)
    {
        return 2;
    }
    else
    {
        return calc(i - 1) + calc(i - 2) + calc(i - 3);
    }
}

最后在主函数中输出 calc(i) 即可。

递推法(DP法)

我们可以发现递归法虽简单,但由于调用栈在 \(i\) 大到一定程度时会过于庞大,且有多次重复运算(如 \(i\)\(10\)calc(4) 就调用了至少 \(16\) 次),那有没有解决的办法呢?

有!我们把之前的计算结果记下来不就行了,计算出一个我就记一个,时间复杂度直接下降到 \(O(n)\)

直接出代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    scanf("%d", &n);
    vector<int> vec;
    vec.resize(n);
    vec[0] = 1;
    vec[1] = 1;
    vec[2] = 2;
    for (int i = 3; i < n; ++i)
    {
        vec[i] = vec[i - 1] + vec[i - 2] + vec[i - 3];
    }
    printf("%d", vec[n - 1]);
    return 0;
}

5. 旺财开关灯

有一种灯,按一下开关会反转它的状态,如开灯变关灯,再按一下又开灯。现在有 \(n\) 盏灯,每一盏一开始都是灭的,但淘气给所有灯按了若干下,请求出所有灯现在的状态(亮、灭)。

首先,这盏神奇的灯有一个最基本的性质:按一下开关会反转它的状态。在此基础上,我们知道,给同一盏灯按偶数下会使灯的状态保持不变。所以如果灯 \(A\) 按了偶数下,根据上面的结论,它的状态不变,所以它仍然熄灭;如果按了奇数下,同理,它的状态会反转,也就是由开始的“灭”变为“亮”。

直接上代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
    {
        int m;
        scanf("%d", &m);
        if (m & 1)  // 更快的奇偶判断方式
        {
            printf("1");  // 亮
        }
        else
        {
            printf("1");  // 灭
        }
    }
    return 0;
}