2023蜀山区小学组信息学竞赛分析
这次小学组市赛还是比较简单的,接下来就带大家简单看看这几题。
T1 连续字符(char)
题目描述
为了吸引参观者,负责园博会信息化展厅建设的小明设计了一个互动节目,参观者找到屏幕上按字典顺序连续的字符串会有礼品,礼品价值和字符长度成正比。例如,ABC
是按字典顺序连续的字符串,而 AAB
和 ABD
都不是。屏幕上的字符串已经将所有字符排序,现在请你找出它的最长字典顺序连续子串。这里,子串指的是字符串的一部分,例如 D
、AB
、ABD
都是 ABD
的子串。
输入格式
第一行是 1 个整数 N ,表示字符串的长度。
之后一行一个仅包括大写字母的字符串。
输出格式
输出按字典顺序连续的最长子串长度。
样例
3
ABG
2
解释#1
子串 AB
是按字典顺序连续的,且没有比它更长的符合题意的子串。
5
KLMPQ
3
18
ACDEGHIKNOPQSTUWYZ
4
解释#3
一个长度为 4 且按字典顺序连续的子串是 NOPQ
。没有比它更长的符合题意的子串。
数据范围
1 ≤ N ≤ 26
分析
这题比较水,主要考数组连续性,注意一下条件判断和s的赋值即可。
代码
#include <bits/stdc++.h>
using namespace std;
int n, s = 1, maxn;
string a;
int main() {
freopen("char.in", "r", stdin);
freopen("char.out", "w", stdout);//文件操作
cin >> n >> a;
for (int i = 1; i < a.size(); i++) {
if (a[i] == a[i - 1] + 1) {
s++;
} else {
maxn = max(maxn, s);
s = 1;
}
}
maxn = max(maxn, s);
cout << maxn;
return 0;
}
T2 寻找座位(seat)
题目描述
园博会的展区面积很大,接驳不同展区间的电动车需要提前预约,参观者凭成功预约信息才能坐车。因此发车前会进行频繁的订票/退票操作。现在有一辆特殊电动车,里面有 N 排,每排 5 个座位,每个座位用 1 表示已预订,0 表示未预订。小明负责安排这辆车下一趟的座位,按时间顺序收到了 M 个订票(D
)或者退票(T
)信息,请你帮小明编写程序,看剩余座位是否能满足每一个要求。
输入格式
第一行是两个正整数 N 和 M,N 表示园博会电动车上的座位排数,M 表示系统收到的订/退票信息。
接下来是 N 行,每行 5 个数字,表示座位是否被占用,0 表示未被占用,1表示已经占用。
N 行座位信息后是 M 行订票/退票操作,其中 D
表示订票、T
表示退票。
输出格式
针对 M 个订票/退票操作,按顺序给出座位是否能满足需求的判断结果,Yes
表示可以满足要求,No
表示不能满足。
样例
6 4
11111
11101
11011
11111
10001
10001
D 5
T 2
D 6
T 3
Yes
Yes
No
Yes
解释#1
满足了前两个需求后,不再有足够的座位满足第三个需求。第三个需求应该被拒绝并忽略其影响。
数据范围
1 ≤ 𝑁 ≤ 1000,1 ≤ 𝑀 ≤ 100000,1 ≤ 单次订退票数量 ≤ 10000
分析
这题也很简单,后两题再详细说,这里只需要注意一下判断就好了。
代码
#include <bits/stdc++.h>
using namespace std;
int n, m, c, s1, s2;
char d;
string a;
int main() {
freopen("seat.in", "r", stdin);
freopen("seat.out", "w", stdout);//文件操作
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a;
for (int j = 0; j < a.size(); j++) {
if (a[j] == '1') {
s1++;
} else {
s2++;
}
}
}
for (int i = 1; i <= m; i++) {
cin >> d >> c;
if (d == 'D') {
if (c <= s2) {
s2 -= c, s1 += c;
cout << "Yes\n";
} else {
cout << "No\n";
}
} else {
if (c <= s1) {
s1 -= c, s2 += c;
cout << "Yes\n";
} else {
cout << "No\n";
}
}
}
return 0;
}
T3 限速路段(road)
题目描述
园博会的某路段上有 N 个路牌,相邻两个路牌之间间隔 10 千米,这些路牌将这个路段划分为等间距的 N-1 个区间。路牌有两种类型:
(1)限速,接下来的全部区间的速度都不能超过标识值;
(2)取消限速,取消最近的一个与标识值相同的限速。其中,限速路牌用正整数表示,取消限速路牌用负整数表示,其真实标识值等于输入数据的绝对值。例如,60 表示限速 60 的路牌,而 -60 表示取消限速 60 的路牌。
假设车辆在通过路牌的瞬间可以立即变速,那么通过此路段且不违反限速的最短用时是多少?多个限速同时生效时,车辆的速度应不超过有效的最低限速。
本题中速度单位均为千米每小时。
输入格式
输入的第 1 行包含 2 个整数 N,M 依次表示路牌的数量和车辆的最高时速。
接下来 1 行 N 个整数,按顺序表示遇到的路牌。
输出格式
输出 1 行 1 个数,表示答案。保留两位小数输出。
样例
5 100
10 -10 30 20 40
1.93
解释#1
在第 1 个区间速度 10,用时 1;第 2 个区间速度 100,用时 0.1;第 3 个区间速度 30,用时 1/3;第 4 个区间速度 20,用时 0.5。
6 100
40 40 -40 30 30 30
1.42
解释#2
在第 3 个区间,取消了一个限速 40,但还有另一个限速 40 生效,因此速度仍然为 40。
4 100
10 40 -40 1
3.00
解释#3
在第 3 个区间,取消了限速 40,但限速 10 仍然生效。
4 100
50 40 -40 1
0.65
解释#4
在第 3 个区间,取消了限速 40,但限速 50 仍然生效。
数据范围
1 ≤ N ≤ 100000,1 ≤ M ≤ 100,−100 ≤ 路牌数值 ≤ 100。输入数据中不含有 0。
分析
一定要记得S(统计时间的变量)要是double类型
我们看一下这个样例:
4 100
10 40 -40 1
3.00
很多人算的答案是2.25,但是按题意,-40只是取消了40的限速,前面还有一个10的限速,所以最终答案是3.00。
这样我们就有了一个思路:数组计数。
我们来看具体实现:
int x = m;
for (int j = 1; j <= 100; j++) {
if (f[j] != 0) {
x = min(x, j);//取最小值
break;
}
}
总体代码
#include <bits/stdc++.h>
using namespace std;
long long n, m, a, b[1005];
double s;
int main() {
freopen("road.in", "r", stdin);
freopen("road.out", "w", stdout);//文件操作
cin >> n >> m;
for (int i = 1; i < n; i++) {
cin >> a;
if (a > 0) {
b[a]++;
} else if (b[-a]) {
b[-a]--;
}
int f = m;
for (int j = 1; j <= 100; j++) {
if (b[j]) {
f = min(f, j);
break;//找到直接break
}
}
s += 10.0 / f;
}
cin >> m;
cout << fixed << setprecision(2) << s;//保留两位小数
return 0;
}
T4 观战排队(queue)
<h3>题目描述</h3>
园博会吸引了很多参观者,为了保证参观质量,小明负责控制每个展区的人数,暂时无法入馆的参观者需要排队等候。小明为排队的参观者设计了一个小游戏,规则如下:
假定现在有 N 位参观者排成一列,将他们从左往右编号为 1 至 N。如果两位参观者 I,J(I
输入格式
输入的第 1 行包含 1 个整数 N,表示队列中的人数。
接下来 1 行 N 个整数,第 I 个数表示参观者 I 的身高。
输出格式
输出 1 行 1 个整数,表示答案。
样例
4
175 160 180 165
4
解释#1
1,2 2,3 3,4 1,3 可以互相看见。
5
10 20 30 20 10
4
解释#2
尽管参观者 3 能够看见参观者 1,但是参观者 1 不能看见参观者 3。因此 1,3 不能互相看见。
数据范围
分析
这题看数据范围很大啊
但是你知道吗,暴力代码能过官方数据(可见官方数据并没有多么严格)
在我编程机构的网站暴力代码只能拿82分。
至于满分代码,需要用到单调栈 我 不 会
水平不高的我只会暴力了。。。
代码
#include <bits/stdc++.h>
using namespace std;
long long n, a[1000005], s;
int main() {
freopen("queue.in", "r", stdin);
freopen("queue.out", "w", stdout);//文件操作
ios::sync_with_stdio(0);
cin.tie(0);//快读
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
s += n - 1;//这里是因为站在一起的两个人一定能看到对方,共n-1组,提前加上,减少循环次数
for (int i = 1; i <= n; i++) {
for (int j = i + 2; j <= n; j++) {
int f = 0;
for (int k = i + 1; k < j; k++) {
if (a[k] < a[i] && a[k] < a[j]) {
;
} else {
f = 1;
break;
}
}
if (f == 0) {
s++;
}
}
}
cout << s;
return 0;
}
本人水平不高,讲解十分粗略,请见谅~
估分数线在 180-210
本篇就这么多啦(´▽`ʃ♡ƪ)