2024 年 9 月青少年软编等考 C 语言三级真题解析
目录
- T1. 爆气球
-
- 思路分析
- T2. 乘法小宇宙
-
- 思路分析
- T3. 有多少坑
-
- 思路分析
- T4. 势均力敌
-
- 思路分析
- T5. 买地攻略
-
- 思路分析
T1. 爆气球
爆气球对孩子们来说是很好玩的游戏。假设有 n n n 只气球被布置在一条直线上,游戏的目标很简单,就是爆掉尽可能多的气球。但是这里我们加一条特殊的规则 —— 你只能跳一次。我们假设聪明的娃穿了件浑身带刺的衣服,跳到某个位置,躺平,这样气球只要碰到娃身体的任何部分都会立刻爆炸。那么你的任务就是告诉娃应该跳到哪里,才能一次爆掉最多的气球。
时间限制:1 s
内存限制:64 MB
- 输入
输入第一行两个正整数: n n n( ≤ 1 0 5 ≤ 10^5 ≤105)为一条线上布置的气球的数量; h h h( ≤ 1 0 3 ≤ 10^3 ≤103)为孩子伸直双臂能达到的高度。
第二行给出 n n n 个整数,每个对应一只气球在直线轴上的坐标。题目保证坐标按递增顺序给出,所有坐标值在 [ − 1 0 6 , 1 0 6 ] [-10^6, 10^6] [−106,106] 区间内。 - 输出
在一行中输出孩子跳跃的位置坐标,使得孩子跳到这个位置然后躺平能够爆掉身下最多的气球;随后输出能爆掉的气球的最大数量。如果这个坐标不唯一,输出最小的那个值。一行中的数间应有 1 1 1 个空格。 - 样例输入
11 120 -120 -40 0 80 122 140 160 220 240 260 300
- 样例输出
120 5
- 提示
跳到从 120 120 120 到 140 140 140,或 240 240 240 到 260 260 260 之间的任何位置,都可以爆掉 5 5 5 只气球,所以 120 120 120 作为最小的坐标被输出。
思路分析
此题考查枚举算法,属于基础题。
可以用尺取法来高效完成枚举操作,具体来说,设置一个左指针 L L L,初始时为 1 1 1,表示从第一个气球所在的位置开始。然后依次枚举每一个气球 a i a_i ai,其中 i i i 作为右指针。为了能够覆盖到右指针 i i i,我们需要根据尺子的长度(娃伸直双臂能够达到的高度 h h h)将左指针 L L L 移动到合适的位置。移动过程中同时更新尺子覆盖到的气球数量,左指针 L L L 移动结束后,再更新一次气球数量。然后根据此时覆盖到的气球数量更新答案,由于需要给出最小的坐标,因此应该用 a i − h a_i - h ai−h 作为当前的坐标,而不是 a L a_L aL。
/*
* Name: T1.cpp
* Problem: 爆气球
* Author: Teacher Gao.
* Date&Time: 2025/02/15 09:04
*/
#include <iostream>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, h, a[100005] = {
0};
cin >> n >> h;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int L = 1, tot = 0, ans = 0, ansx;
for (int i = 1; i <= n; i++) {
while (a[L] + h < a[i]) {
L++, tot--;
}
tot++;
if (tot > ans) {
ans = tot, ansx = a[i] - h;
}
}
cout << ansx << " " << ans << endl;
return 0;
}
T2. 乘法小宇宙
一个 n n n 位数的正整数 A = a n a n − 1 . . a 1 A=a_na_{n-1}..a_1 A=anan−1..a1 和另一个 2 2 2 位数的正整数 B = b 2 b 1 B=b_2b_1 B=b2b1 相乘,其乘法展开式如下图所示:
其中 C = c n + 1 c n . . c 1 C=c_{n+1}c_n..c_1 C