2023蜀山区小学组信息学竞赛分析

这次小学组市赛还是比较简单的,接下来就带大家简单看看这几题。

T1 连续字符(char)

题目描述

为了吸引参观者,负责园博会信息化展厅建设的小明设计了一个互动节目,参观者找到屏幕上按字典顺序连续的字符串会有礼品,礼品价值和字符长度成正比。例如,ABC 是按字典顺序连续的字符串,而 AABABD 都不是。屏幕上的字符串已经将所有字符排序,现在请你找出它的最长字典顺序连续子串。这里,子串指的是字符串的一部分,例如 DABABD 都是 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 不能互相看见。

数据范围

  • 对于全部数据,有 1 ≤ 𝑁 ≤ 1000000,1 ≤ 身高 ≤ 1000000。

    分析

    这题看数据范围很大啊

    但是你知道吗,暴力代码能过官方数据(可见官方数据并没有多么严格)

    在我编程机构的网站暴力代码只能拿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

    本篇就这么多啦(´▽`ʃ♡ƪ)

  • posted @ 2023-10-29 21:21  Befrepof  阅读(655)  评论(0编辑  收藏  举报