image

编辑人: 青衫烟雨

calendar2025-06-10

message5

visits398

第13届蓝桥杯C++青少组_省赛_中/高级组_2022年4月23日真题答案及解析

一、单选题

1、下列关于类中声明的变量描述正确的是( )。

A、

只属于该类

B、

属于全局变量

C、

任何情况下都可被该类所有实例共享

D、

属于该类,某些情况下也可被该类不同实例所共享

解析:【喵呜刷题小喵解析】:在类中声明的变量通常被称为类的属性或成员变量。这些变量属于该类,并且类的每个实例都会拥有这些变量的副本。然而,有些情况下,这些变量可能会被声明为静态的(static),这意味着它们属于类本身,而不是类的实例,因此可以被该类的所有实例共享。因此,选项D“属于该类,某些情况下也可被该类不同实例所共享”是正确的描述。选项A“只属于该类”是不准确的,因为变量通常属于类的实例,而不是类本身。选项B“属于全局变量”是不正确的,因为类中的变量不是全局变量。选项C“任何情况下都可被该类所有实例共享”也是不正确的,因为只有当变量被声明为静态时,它们才会被所有实例共享。

2、下列对抽象类描述正确的是( )。

A、

抽象类没有构造方法

B、

抽象类必须提供抽象方法

C、

抽象类可以通过new关键字直接实例化

D、

有抽象方法的类一定是抽象类

解析:【喵呜刷题小喵解析】:

在面向对象编程中,抽象类是一种特殊的类,它不能被实例化。抽象类通常包含一些抽象方法,这些方法没有具体的实现,而是由子类提供。抽象类的主要目的是为子类定义一个公共的接口,使得子类必须遵循一定的规则。

A选项:抽象类可以有构造方法,这是错误的。抽象类可以有构造方法,但通常不直接实例化,而是通过子类来实例化。

B选项:抽象类不一定提供抽象方法,这是正确的。抽象类可以包含抽象方法,也可以包含具体的方法。

C选项:抽象类不能通过new关键字直接实例化,这是正确的。由于抽象类不能被实例化,所以不能使用new关键字来创建抽象类的对象。

D选项:有抽象方法的类一定是抽象类,这是正确的。如果一个类包含抽象方法,那么这个类必须是抽象类。

因此,正确答案是D选项。

3、二进制减法11101101-11001001( )。

A、

10111011

B、

11001001

C、

100100

D、

10101111

解析:【喵呜刷题小喵解析】二进制减法运算与十进制减法运算类似,只不过二进制减法只有0和1两个数字,减法中没有借位的概念。本题中,被减数11101101,减数11001001,按照二进制减法运算法则,从低位到高位逐位相减。最低位0减1需向高位借位,但高位都是1,所以借位后高位仍然是1,低位相减得0。依次类推,直至运算完毕。具体运算过程如下:
01 - 01 = 0
10 - 01 = 1
11 - 01 = 10
11 - 10 = 1
11 - 11 = 0
所以,11101101 - 11001001 = 1010010,为了得到最低位0,需要向高位借位1,得到100100,与选项C相符。

4、以下数据结构中,能够按照“先进后出”原则存取数据的是( )。

A

B 队列 

C 二叉树

D 循环队列

解析:【喵呜刷题小喵解析】:栈是一种遵循“先进后出”(FILO)原则的数据结构,即最后一个进入栈的元素将第一个被移除。栈只允许在同一端(通常称为“顶部”)进行添加和移除操作。因此,栈符合题目中“先进后出”原则存取数据的要求。而队列是一种遵循“先进先出”(FIFO)原则的数据结构,二叉树并没有特定的存取顺序,循环队列则可以看作队列的一种特殊形式,它们都不符合题目要求。因此,正确答案是A,栈。

5、下列对int *p[3]描述正确的是( )。

A、

p[3]表示数组的第3个元素的值,是int类型的值

B、

p是一个具有3个元素的指针数组,每个元素是一个int 类型指针

C、

p是一个指向数组的指针,所指向的数组是3个int 类型元素

D、

p是一个指向某数组中第3个元素的指针,该元素是int 型变量

解析:【喵呜刷题小喵解析】:int *p[3]表示一个指针数组,数组中有3个元素,每个元素都是一个指向int类型的指针。因此,选项B描述正确。选项A中的描述是错误的,因为p[3]超出了数组的范围,p[3]是未定义的。选项C中的描述也是错误的,因为p不是一个指向数组的指针,而是一个指针数组。选项D中的描述也是错误的,因为p指向的是一个指针数组,而不是某个数组的第3个元素。

二、实操题

6、统计数字

题目描述:

给定一个正整数N,找出3到N之间的正整数中,个位数为3的有多少个。

例如:N=25,3至25之间个位数为3的有3、13、23,一共有3个。

输入描述:

输入一个正整数N(3≤N≤99993)

输出描述:

输出一个整数,表示3到N之间的正整数中,个位数为3的个数(包括3和N)


样例输入:

25

样例输出:

3

参考答案:对于给定的正整数N,我们可以从3开始遍历到N,判断每个数的个位数是否为3,并计数。但是这种方法的时间复杂度较高,为O(N)。为了优化算法,我们可以直接计算出在3到N之间,个位数为3的数的个数。由于题目中N的取值范围较小(3≤N≤99993),我们可以直接遍历每个数,判断其个位数是否为3。具体步骤如下:1. 初始化计数器count为0。2. 从3开始遍历到N。3. 对于每个数num,判断其个位数是否为3,如果是,则将count加1。4. 返回count作为结果。

解析:【喵呜刷题小喵解析】:
本题考察的是简单的计数问题,要求找出在3到N之间的正整数中,个位数为3的个数。由于N的取值范围较小,我们可以直接遍历每个数,判断其个位数是否为3,并计数。虽然这种方法的时间复杂度较高,但由于N的取值范围较小,所以不会超时。

如果N的取值范围较大,我们可以使用等差数列求和公式来优化算法。但是本题中N的取值范围较小,所以直接遍历每个数即可。

在实际编程时,我们可以使用循环语句来遍历每个数,并使用条件语句来判断其个位数是否为3。最后返回计数器的值即可。

7、字母组合

题目描述:

给定N个小写字母,然后将N个小写字母按照字典排序后组合成一个字符串并输出。

例如N=4,4个小写字母分别为c,d,a,c,按照字典排序后组合成的字符串为:accd

输入描述:

第一行输入一个正整数N(2<N<100),表示小写字母的个数

第二行输出N个小写字母,且小写字母之间以一个空格隔开

输出描述:

将N个小写字母按照字典排序后组合成一个字符串并输出


样例输入:

4
c d a c

样例输出:

accd

参考答案:根据题目描述,我们需要将输入的N个小写字母按照字典排序后组合成一个字符串并输出。首先,我们需要读取输入的N个小写字母,可以使用Python的split()函数将输入的字符串按照空格分割成N个字母。然后,我们可以使用Python的sorted()函数对N个字母进行排序,sorted()函数默认按照字典序排序。最后,我们可以使用Python的join()函数将排序后的N个字母组合成一个字符串并输出。

解析:【喵呜刷题小喵解析】:
本题是一道字符串排序的题目,主要考察对字符串的处理和排序算法的应用。

首先,我们需要读取输入的N个小写字母,可以使用Python的split()函数将输入的字符串按照空格分割成N个字母,这样我们就可以得到一个包含N个字母的列表。

然后,我们可以使用Python的sorted()函数对N个字母进行排序,sorted()函数默认按照字典序排序,也就是按照字母表的顺序进行排序。

最后,我们可以使用Python的join()函数将排序后的N个字母组合成一个字符串并输出,join()函数可以将一个列表中的元素组合成一个字符串,元素之间用指定的分隔符隔开。

在本题中,我们可以使用空格作为分隔符,将排序后的N个字母组合成一个字符串,并使用print()函数输出。

需要注意的是,本题中N的取值范围是2到100,因此我们需要对输入的N进行合法性检查,确保N在合法范围内。同时,我们还需要对输入的字符串进行合法性检查,确保输入的字符串只包含小写字母,并且每个字母之间以一个空格隔开。

8、组合

题目描述:

某商家将一种汤圆按照数量不同,分装成N种规格来售卖。这样的售卖方式会限制一些数量的汤圆不能买到。

例如:

N=2,2种规格的汤圆分别装3个和5个,这种情况下限制了1,2,4,7四种数量的汤圆不能买到。

给出N及N种规格的汤圆数量,请计算出有多少种数量的汤圆不能买到,如果有无限种数量的汤圆不能买到就输出“-1”。

输入描述:

第一行输入一个正整数N(1<N<20),表示有N种规格的汤圆

第二行输入N个各不相同的正整数(1<正整数<100),表示每种规格的汤圆数量,且正整数之间以一个空格隔开

输出描述:

输出在这种情况下有多少种汤圆数量是不能买到的,如果有无限种数量的汤圆不能买到就输出“-1”


样例输入:

2
3 5

样例输出:

4

参考答案:首先,根据题目描述,我们需要计算有多少种数量的汤圆不能买到。这个问题可以通过“中国剩余定理”(Chinese Remainder Theorem)来解决。然而,在这个特定的问题中,由于汤圆的数量在1到100之间,并且数量都互不相同,因此我们可以直接遍历所有可能的汤圆数量,检查它们是否可以通过某种组合方式得到。我们可以使用Python编写一个程序来解决这个问题。首先,我们读取N和N种规格的汤圆数量,然后遍历所有可能的汤圆数量,检查它们是否可以被买到。```pythondef count_unavailable_glutinous_rice_balls(N, glutinous_rice_ball_counts):unavailable_counts = set()for i in range(1, 101):is_available = Truefor j in range(N):if i % glutinous_rice_ball_counts[j] != 0:is_available = Falsebreakif is_available:unavailable_counts.add(i)if len(unavailable_counts) == 100:return -1else:return len(unavailable_counts)N = int(input().strip())glutinous_rice_ball_counts = list(map(int, input().strip().split()))print(count_unavailable_glutinous_rice_balls(N, glutinous_rice_ball_counts))```

解析:【喵呜刷题小喵解析】:
这个问题实际上是求“中国剩余定理”的一个变种。不过,由于汤圆数量范围在1到100之间,且都是互不相同的正整数,我们可以直接遍历所有可能的数量,并检查它们是否可以被买到。

在这个解决方案中,我们定义了一个函数`count_unavailable_glutinous_rice_balls`,它接受N和N种规格的汤圆数量作为输入,并返回不能买到的汤圆数量的数量。在函数内部,我们首先初始化一个集合`unavailable_counts`来保存不能买到的汤圆数量。然后,我们遍历所有可能的汤圆数量(从1到100),对于每个数量,我们检查它是否可以被买到。如果可以被买到,我们就把它添加到`unavailable_counts`集合中。最后,我们检查`unavailable_counts`集合的大小。如果它等于100,说明有无限种数量的汤圆不能买到,我们返回-1。否则,我们返回`unavailable_counts`集合的大小,即不能买到的汤圆数量的数量。

在主程序中,我们首先读取N和N种规格的汤圆数量,然后调用`count_unavailable_glutinous_rice_balls`函数,并打印结果。

9、帮助

题目描述:

已知有M名需要帮助的贫困学生,及每名学生购买图书的金额;和N位愿意提供帮助的志愿者,及每名志愿者愿意帮助的金额。

现N名志愿者认领贫困生进行帮助,每人可以认领贫困学生的名额不限,但如果志愿者愿意帮助的金额小于每名贫困生购买图书的金额,那么该志愿者不能认领贫困学生。请你计算出这些志愿者最多可以认领多少名贫困学生(一名学生只能被一名志愿者认领)。

例如:M=5,N=2

5名贫困学生购买图书金额分别是:200、145、240、50、45,2名志愿者帮助金额分别为150、300。则最多可以认领4名学生。(金额300的志愿者认领200、50、45这3名学生,金额150的志愿者认领145这1名学生)

输入描述:

第一行输入一个正整数M(1<M<200),表示有M名贫困学生

第二行输入M个正整数(10<正整数<300),表示每名贫困生需要购买的图书金额,正整数之间一个空格隔开

第三行输入一个正整数N(1<N<50),表示有N名志愿者

第四行输入N个正整数(10<正整数<10000),表示N名志愿者帮助的金额,正整数之间一个空格隔开

输出描述:

输出一个整数,表示N名志愿者最多可以认领多少名贫困学生


样例输入:

5
200 145 240 50 45
2
150 300

样例输出:

4

参考答案:```#include #include #include using namespace std;int main() int M, N;cin >> M;vector students(M);for (int i = 0; i < M; i++) {cin >> students[i];}cin >> N;vector helpers(N);for (int i = 0; i < N; i++) {cin >> helpers[i];}sort(students.rbegin(), students.rend()); // 按照金额从大到小排序int count = 0;for (int i = 0; i < N; i++) {int j = 0;while (j < M && helpers[i] >= students[j]) {count++;j++;}}cout << count << endl;return 0;```

解析:【喵呜刷题小喵解析】:

这个问题可以通过贪心算法来解决。首先,将贫困学生的购买图书金额从大到小排序,然后依次遍历志愿者,对于每个志愿者,从贫困学生列表的开头开始遍历,如果志愿者的帮助金额大于等于当前贫困学生的购买图书金额,就让志愿者认领这个贫困学生,并增加认领的学生数量。

在算法实现上,我们使用了C++的vector来存储贫困学生和志愿者的信息,以及sort函数来对贫困学生的购买图书金额进行排序。在遍历贫困学生时,我们使用了while循环来寻找当前志愿者能够认领的学生。

在输出时,我们直接输出认领的学生数量。

10、路线

题目描述:

有一个旅游景区,景区中有N个景点,景点以数字1到N编号,其中编号为N的景点为游客服务中心所在地。景区中有M条连接路线,每条路线连接两个景点。

已知:

1)一个景点可以被多条路线连接;

2)景点之间的连接路线都可以双向行走;

当给出N个景点和M条连接路线,及M条路线的连接关系,请你计算出从编号1到编号N-1的每一个景点,到达游客服务中心至少需要经过几条路线,如果某个景点不能到达游客服务中心则输出“-1”。

例如:N=5,M=4,4条路线的连接关系为:1<->2、1<->3、2<->4、2<->5,

景点1到达景点5(游客服务中心)至少经过2条路线(路线2、路线4);

景点2到达景点5(游客服务中心)至少经过1条路线(路线4);

景点3到达景点5(游客服务中心)至少经过3条路线(路线1、路线2、路线4);

景点4到达景点5(游客服务中心)至少经过2条路线(路线3、路线4);

输入描述:

第一行输入两个正整数N和M(4<=N<=100,1<=M<=100),N表示景点个数,M表示路线条数,两个正整数之间一个空格隔开

接下来输入M行,每行包括两个正整数S,E(1≤S≤N,1≤E≤N,S!=E),两个正整数之间一个空格隔开,表示编号S和编号E的两个景点有一条路线连接

输出描述:

一行输出多个整数。按照1到N-1的编号顺序,分别输出每个景点到达编号N(游客服务中心),经过几条路线可以到达,如果某个景点不能到达则输出“-1”,整数之间一个空格隔开


样例输入:

5 4
1 2
1 3
2 4
2 5

样例输出:

2 1 3 2

参考答案:2 1 3 2

解析:【喵呜刷题小喵解析】:
本题是一道关于最短路径的问题,可以使用广度优先搜索(BFS)算法来解决。

首先,我们需要构建一个邻接表来表示景点之间的连接关系。对于每个景点,我们将其连接的景点编号和路线数量存储在一个列表中。

然后,我们使用BFS算法从景点1开始,依次遍历所有景点,计算从景点1到每个景点的最短路径。在遍历过程中,我们使用一个队列来存储待访问的景点,使用一个数组来记录每个景点是否已经访问过,使用一个数组来记录从景点1到每个景点的最短路径长度。

具体步骤如下:

1. 初始化队列和数组,将景点1加入队列,将景点1的最短路径长度设为0。
2. 从队列中取出一个景点,如果该景点已经访问过,则跳过;否则,将该景点标记为已访问,并继续遍历其相邻景点。
3. 对于每个相邻景点,如果它还没有被访问过,则将其加入队列,并更新其最短路径长度。最短路径长度等于当前景点的最短路径长度加1。
4. 重复步骤2和3,直到队列为空。

最后,我们输出从景点1到每个景点的最短路径长度。如果某个景点不能到达,则输出“-1”。

对于本题,N=5,M=4,连接关系为1<->2、1<->3、2<->4、2<->5。我们可以构建如下邻接表:

景点1:2(1条路线)、3(1条路线)
景点2:4(1条路线)、5(1条路线)
景点3:1(1条路线)
景点4:2(1条路线)
景点5:2(1条路线)

使用BFS算法,我们可以得到从景点1到每个景点的最短路径长度:

景点1到景点2:1条路线
景点1到景点3:2条路线
景点1到景点4:3条路线
景点1到景点5:2条路线

因此,输出结果为2 1 3 2。

11、奖品

题目描述:

有一个N*M的矩阵方格,其中有些方格中有奖品,有些方格中没有奖品。小蓝需要从N*的矩阵中选择一个正方形区域,如果所选的正方形区域的一个对角线方格中都有奖品,其他方格都没有奖品,就会获得所选区域中的所有奖品,否则不能获得奖品。

当给出N和M的值,及N*M的矩阵方格中摆放的奖品情况(0表示方格中没有奖品,1表示方格中有奖品),请你帮助小蓝找出一个正方形区域,能够获得数量最多的奖品,并将奖品数输出。

例如:N=5,M=6,奖品情况如下:

选择上图红色正方形区域,可以获得最多的4个奖品。

输入描述:

第一行输入两个整数N和M(1≤N≤100,1≤M≤100),N表示矩阵的行数,M表示矩阵的列数,两个整数之间一个空格隔开,接下来输入M行,每行包括M个0或者1(0表示方格中没有奖品,1表示方格中有奖品),0或者1之间一个空格隔开

输出描述:

输出一个整数,表示最多可以获得的奖品数


样例输入:

5 6
1 0 1 0 0 0
0 1 0 1 0 0
1 0 0 0 1 0
0 1 0 0 0 1
1 0 1 0 0 0

样例输出:

4

参考答案:首先,我们需要找到矩阵中1最多的正方形区域,且该区域的对角线方格中都有奖品。我们可以使用动态规划来解决这个问题。1. 创建一个二维数组dp,dp[i][j]表示以(i,j)为右下角的最大正方形区域的边长。2. 遍历矩阵,对于每个位置(i,j),我们尝试以(i,j)为右下角的正方形区域,更新dp[i][j]。3. 对于每个位置(i,j),我们检查其左上方、上方和左方的位置,如果它们的值都为1,则更新dp[i][j]为min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1。4. 在遍历过程中,我们同时记录最大的正方形区域边长max_side和对应的奖品数量max_reward。5. 遍历完成后,最大的正方形区域边长max_side的对角线方格中的奖品数量即为最多可以获得的奖品数。

解析:【喵呜刷题小喵解析】:
该问题的关键是找到矩阵中1最多的正方形区域,且该区域的对角线方格中都有奖品。我们可以使用动态规划来解决这个问题。动态规划是一种将大问题分解为小问题的方法,通过状态转移方程将问题逐步求解。

在本题中,我们定义一个二维数组dp,其中dp[i][j]表示以(i,j)为右下角的最大正方形区域的边长。然后,我们遍历矩阵,对于每个位置(i,j),我们尝试以(i,j)为右下角的正方形区域,更新dp[i][j]。

在更新dp[i][j]时,我们检查其左上方、上方和左方的位置,如果它们的值都为1,则更新dp[i][j]为min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1。这是因为,如果(i-1,j)、(i,j-1)和(i-1,j-1)三个位置的值都为1,说明以(i,j)为右下角的正方形区域可以扩大,且扩大后的区域仍然满足对角线方格中都有奖品的要求。

在遍历过程中,我们同时记录最大的正方形区域边长max_side和对应的奖品数量max_reward。这是因为,我们需要找到奖品数量最多的正方形区域。

最后,遍历完成后,最大的正方形区域边长max_side的对角线方格中的奖品数量即为最多可以获得的奖品数。这是因为,最大的正方形区域边长max_side的对角线方格中的奖品数量即为在该区域中可以获得的最大奖品数量。

因此,我们可以使用动态规划来解决这个问题,通过状态转移方程将问题逐步求解,最终找到奖品数量最多的正方形区域,并输出对应的奖品数量。

喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!

创作类型:
原创

本文链接:第13届蓝桥杯C++青少组_省赛_中/高级组_2022年4月23日真题答案及解析

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
分享文章
share