前言
比赛是深圳市龙岗区的小学生信息学奥林匹克竞赛,下面讲题时会概括题目,要原题的找我,如果要的人多会放在评论区。
说真的,没想到疫情三年后的第一场比赛就这么水,8:30 进去的,9:10 出来的,40 分钟光速 AK。
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;
}
标签:int,printf,个数,方格,2023,游记,圆环,vec,LGOI
From: https://www.cnblogs.com/laialaodi/p/17456082.html