2025年7月13日全国青少年信息素养大赛C++编程小学组复赛真题+答案解析

2025年7月13日全国青少年信息素养大赛C++编程小学组复赛真题+答案解析

编程题

1. 种树

题目描述
学校组织植树活动,每个班级都需要种植固定数量的树苗。已知共有若干个班级参与。请问总共需要准备多少棵树苗?

输入描述
一行,两个正整数 mn,分别表示每个班级分到的树苗数量和班级数量

输出描述
一行,一个正整数,表示需要准备的树苗数量

样例输入
5 3

样例输出
15


题目解析
题目要求根据每个班级分配的树苗数量以及班级数量,计算出总共需要准备的树苗数,本质就是简单的乘法运算应用。


解题步骤

  1. 从输入获取每个班级分到的树苗数量 m 和班级数量 n
  2. 通过乘法运算 m * n 得到总共需要准备的树苗数量。
  3. 输出计算得到的总树苗数量。

代码实现

#include <iostream>
using namespace std;
int main() {   
    int m, n;    
    // 从输入读取每个班级分到的树苗数量m和班级数量n
    cin >> m >> n;    
    // 计算总树苗数量(每个班级数量 × 班级数量)
    int tot = m * n;    
    // 输出总树苗数量
    cout << tot << endl;    
    return 0 ;
}

知识点总结

  1. 输入输出:学会使用 cin 从控制台读取输入数据,使用 cout 向控制台输出数据。
  2. 基本运算:掌握乘法运算在实际问题中的应用。

2. 整数分类

题目描述
给定 nt,将1到 n 之间的所有正整数分为两类: A 类数可以被 t 整除(也就是说是 t 的倍数),而 B 类数不能。请输出这两类数的和。

输入描述
一行,两个正整数 nt

输出描述
一行,两个正整数,分别表示 A 类数的和、B 类数的和,两者用空格间隔。

样例1输入
10 3

样例1输出
18 37

解释
A类数(3的倍数):3, 6, 9 → 和为3 + 6 + 9 = 18
B数(非3的倍数):1, 2, 4, 5, 7, 8, 10 → 和为1 + 2 + 4 + 5 + 7 + 8 + 10 = 37

样例2输入
5 2

样例2输出
6 9

解释
A类数(2的倍数):2, 4 → 和为2 + 4 = 6
B类数(非2的倍数):1, 3, 5 → 和为1 + 3 + 5 = 9


题目解析
题目要求对1到 n 的整数按能否被 t 整除进行分类,并分别计算两类数的和,核心是对循环遍历和条件判断的运用。


解题步骤

  1. 从输入获取 nt 的值。
  2. 初始化两个变量 AB 分别用于存储A类数和B类数的和,初始值为0。
  3. 使用循环遍历1到 n 的每一个数 i
    • 如果 i 能被 t 整除,将 i 加到 A 中。
    • 否则,将 i 加到 B 中。
  4. 输出 AB 的值,中间用空格隔开。

代码实现

#include <iostream>
using namespace std;
int main() {
    int n, t, A = 0, B = 0;
    // 从输入读取n和t的值
    cin >> n >> t;
    // 遍历1到n的每一个数
    for (int i = 1; i <= n; i++) {
        // 如果i能被t整除
        if (i % t == 0) A += i;
        else
            // i不能被t整除
            B += i;
    }
    // 输出A类数的和与B类数的和,中间用空格隔开
    cout << A << " " << B << endl;
    return 0;
}

知识点总结

  1. 循环结构for 循环用于遍历一定范围内的数。
  2. 条件判断if - else 语句用于判断数是否能被 t 整除,从而进行分类求和。

3. 智慧农业监测系统

题目描述
某智慧农业监测系统需要根据作物生长周期动态调整灌溉方案。系统发现不同年份月份的灌溉天数计算模块存在误差,特别是闰年二月天数计算不准确。请编写程序实现历法校验功能,精确计算指定年份月份对应的自然日数。

输入描述
一行,两个正整数,分别表示年份 y 和月份 m,用空格隔开。

输出描述
一行,一个正整数,表示这个月有多少天。

样例1输入
2000 2

样例1输出
29

样例2输入
2023 4

样例2输出
30


题目解析
本题重点在于根据闰年的判断规则来确定二月的天数,同时要明确其他月份固定的天数,考察对闰年概念和条件判断的掌握。


解题步骤

  1. 从输入获取年份 y 和月份 m
  2. 创建一个数组 days 存储非闰年各月份的天数。
  3. 如果月份 m 是2月:
    • 根据闰年判断规则(年份能被4整除但不能被100整除,或者能被400整除)判断是否为闰年。
    • 如果是闰年,输出29并结束程序。
  4. 如果不是2月或者不是闰年的2月,直接输出数组 days 中对应月份(m - 1)的天数。

代码实现

#include <iostream>
using namespace std;
int main() {
    int y, m;
    // 从输入读取年份y和月份m
    cin >> y >> m;
    // 月份天数数组(非闰年)
    int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    // 如果月份是2月
    if (m == 2) {
        // 闰年判断:能被4整除但不能被100整除,或者能被400整除
        if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) {
            cout << 29;
            return 0;
        }
    }
    // 输出对应月份的天数
    cout << days[m - 1];
    return 0;
}

知识点总结

  1. 数组:用于存储非闰年各月份的天数。
  2. 闰年判断:掌握闰年的判断条件,并能在程序中用条件语句实现。
  3. 条件语句if - else 语句根据不同条件输出不同结果。

4. 星际通信系统

题目描述
在星际通信系统中,传输的数字会因宇宙射线干扰而倒序,请编写程序对接收到的 n 个干扰数字进行修复,输出每个数字原始的正确值。修复规则:将每个数字的各位数完全逆转(例如:123修复为321, 120修复为21)

输入描述
第一行,一个整数 n
第二行 n 个正整数 ai,表示接收到的干扰数字。

输出描述
一行 n 个整数,表示修复后的正确数字,用空格分隔。

样例输入
3
123 320 78

样例输出
321 23 87


题目解析
题目要求对输入的 n 个数字按特定规则(各位数字逆转)进行修复,主要运用循环和数学运算来实现数字的逆转。


解题步骤

  1. 从输入获取数字的个数 n
  2. 定义一个函数 Rev 用于逆转单个数字:
    • 在函数中,初始化一个变量 ans 为0。
    • 使用 while 循环,通过取余和整除操作,将数字的每一位逆转到 ans 中。
    • 输出逆转后的数字,并添加空格。
  3. 定义一个数组 a 用于存储接收到的干扰数字。
  4. 从输入读取 n 个干扰数字存储到数组 a 中。
  5. 遍历数组 a,对每个数字调用 Rev 函数进行逆转输出。

代码实现

#include <iostream>
using namespace std;
const int N = 1e8;
int a[N];
// 定义逆转单个数字的函数
void Rev(int x) {
    int ans = 0;
    // 通过循环将数字x的每一位逆转到ans中
    while (x) {
        ans = ans * 10 + x % 10;
        x /= 10;
    }
    // 输出逆转后的数字,并添加空格
    cout << ans << " ";
    return;
}
int main() {
    int n;
    // 从输入读取数字的个数n
    cin >> n;
    // 从输入读取n个干扰数字存储到数组a中
    for (int i = 0; i < n; i++) cin >> a[i];
    // 遍历数组a,对每个数字调用Rev函数进行逆转输出
    for (int i = 0; i < n; i++) Rev(a[i]);
    return 0;
}

知识点总结

  1. 函数定义与调用:学会定义和调用自定义函数,这里定义 Rev 函数实现数字逆转。
  2. 循环结构while 循环用于数字逆转的过程。
  3. 数组:存储接收到的干扰数字。

5. 小球

题目描述
n 个小球摆成一排,第 i 个小球的颜色为 c,在这一排小球中,你可以选择其中连续的 K 个小球并且获得他们。你喜欢五彩缤纷的颜色,所以你获得的小球不同颜色越多,就越高兴,输出你能获得的最多的小球颜色数。

输入描述
第一行,两个数字 nk,表示一共有多少个小球,以及你可以选择获得其中连续的 K 个小球。
第二行,n 个数字,表示每个小球的颜色 ci

输出描述
一行,一个整数,表示你能获得的最多小球的颜色数量。

样例输入1
5 3
1 2 2 3 1

样例输出1
3

样例解释
输入:n = 5, k = 3
颜色:1 2 2 3 1
第一个窗口[0,2]:颜色[1,2,2] -> 不同颜色数为2(1和2)。
第二个窗口[1,3]:颜色[2,2,3] -> 不同颜色数为2(2和3)。
第三个窗口[2,4]:颜色[2,3,1] -> 不同颜色数为3(2,3,1)。
所以输出3。

数据范围
1 <= n <= 3 * 10^5,1 <= ci <= 1000


题目解析
本题使用滑动窗口算法,通过固定大小为 k 的窗口在小球颜色数组上滑动,统计每个窗口内不同颜色的数量,从而找出最多的不同颜色数。


解题步骤

  1. 从输入获取小球总数 n 和窗口大小 k
  2. 定义两个数组 cs 用于存储每个小球的颜色,cnt 用于记录每种颜色在窗口内的数量。
  3. 特殊处理 k == 0 的情况,直接输出0并结束程序。
  4. 初始化第一个窗口(前 k 个元素):
    • 遍历前 k 个小球的颜色,使用 cnt 数组记录每种颜色的数量。
    • 如果一种颜色首次出现(cnt[cs[i]] == 0),则不同颜色数 ans 加1。
    • 记录此时窗口内不同颜色数的最大值 Max_ansans
  5. 使用循环滑动窗口,窗口长度为 k
    • 移除窗口最左侧的元素,更新其颜色计数(cnt[cs[L]]--)。如果计数降为0,则不同颜色数 ans 减1。
    • 添加窗口右侧的新元素,更新其颜色计数(cnt[cs[R]]++)。如果计数从0增加到1,则不同颜色数 ans 加1。
    • 更新不同颜色数的最大值 Max_ans
  6. 输出 Max_ans,即能获得的最多小球颜色数。

代码实现

#include <iostream>
using namespace std;
const int N = 1e6;
int cs[N], cnt[N];
int main() {
    int n, k;
    // 从输入读取小球总数n和窗口大小k
    cin >> n >> k;
    // 从输入读取每个小球的颜色存储到cs数组
    for (int i = 0; i < n; i++) cin >> cs[i];
    // 特殊处理k = 0的情况
    if (k == 0) {
        cout << 0 << endl;
        return 0;
    }
    int ans = 0, Max_ans = 0;
    // 初始化第一个窗口(前K个元素),统计窗口中不同颜色的数量。
    for (int i = 0; i < k; i++) {
        if (cnt[cs[i]] == 0) ans++;
        cnt[cs[i]]++;
    }
    Max_ans = ans;    // 最大值有颜色种类
    // 滑动窗口,窗口长度为k
    for (int L = 0; L < n - k; L++) { 
        int R = L + k;
        // 移除窗口最左侧的元素,更新其颜色计数。如果计数降为0,则减少不同颜色的数量。
        cnt[cs[L]]--;
        if (cnt[cs[L]] == 0) ans--;
        // 添加窗口右侧的新元素,更新其颜色计数。如果计数从0增加到1,则增加不同颜色的数量。
        if (cnt[cs[R]] == 0) ans++;
        cnt[cs[R]]++;
        // 记录当前窗口中不同颜色的最大值
        if (ans > Max_ans)
            Max_ans = ans;
    }
    // 输出结果
    cout << Max_ans << endl;
    return 0;
}

知识点总结

  1. 滑动窗口算法:理解并掌握滑动窗口在数组上的应用,包括窗口的初始化、滑动以及数据的更新。
  2. 数组:两个数组 cscnt 分别用于存储小球颜色和颜色计数。
  3. 条件判断:在更新窗口内颜色计数时,通过条件判断来确定不同颜色数的变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值