2026年全国青少年信息素养大赛算法应用主题赛C++赛项【决赛】模拟卷3:文末附答案

2026年全国青少年信息素养大赛算法应用主题赛C++赛项【决赛】模拟卷3:文末附答案

一、单选题(每题2分,共10分)
  1. 在C++中,执行以下代码后,输出的结果是( )

    cpp 复制代码
    int a = 5, b = 2;
    double c = a / b;
    cout << c;

    A. 2.5   B. 2   C. 2.0   D. 编译错误

  2. 下列关于数组的说法,错误 的是( )

    A. 数组下标从0开始

    B. 定义数组时,长度可以使用变量(如 int n; cin>>n; int a[n];

    C. 数组名代表数组首地址

    D. 可以定义 string name[50] 存储50个名字

  3. 若定义一个函数 int fun(int x) 用于计算斐波那契数列的第x项,以下哪种实现方式可能导致程序运行时间大幅增加甚至超时?( )

    A. 使用for循环迭代   B. 使用递归但不加记忆化   C. 使用数组记录中间结果   D. 使用递推

  4. 在C++中,判断字符变量 ch 是否为大写字母 的正确表达式是( )

    A. ch >= 'A' && ch <= 'Z'   B. ch >= 65 || ch <= 90

    C. ch >= 'A' || ch <= 'Z'   D. 'A' <= ch <= 'Z'

  5. 关于 breakcontinue 语句,下列说法正确的是( )

    A. continue 用于跳出当前整个循环

    B. 在嵌套循环中,break 只跳出最内层循环

    C. break 只能用于 switch 语句中

    D. continue 可以用于 switch 语句中


二、多选题(每题4分,共20分,多选、错选、漏选不得分)
  1. 下列哪些是C++中合法的标识符(变量名)?( )

    A. _LongMarch   B. 2thDivision   C. RedArmy   D. int

  2. 关于STL容器,下列说法正确的有( )

    A. vector 是动态数组,支持随机访问

    B. set 中的元素会自动去重并排序

    C. map 可以通过键值对存储数据,键可以重复

    D. pair 可以将两个数据组合成一个单元

  3. 以下哪些算法思想属于"以空间换时间"的典型应用?( )

    A. 桶排序(计数排序)   B. 递归求阶乘

    C. 使用数组记录已计算过的斐波那契数列值(记忆化搜索)  D. 暴力枚举

  4. 关于结构体,下列说法正确的有( )

    A. 结构体中可以包含不同数据类型的成员

    B. 结构体变量可以直接整体赋值(如 stu2 = stu1;

    C. 结构体可以作为函数的参数传递

    D. 结构体不支持嵌套定义

  5. 阅读以下程序,可能的输出结果有( )

    cpp 复制代码
    int x = 0;
    for (int i = 1; i <= 10; i++) {
        if (i % 3 == 0) continue;
        x += i;
    }
    cout << x;

    A. 55   B. 37   C. 33   D. 45


三、编程操作题(共70分)
第1题(15分):"丝路驼队"物资调度------贪心思想

题目描述

在丝绸之路上,一支驼队需要运输n批货物翻越沙漠。每批货物有重量w_i。骆驼的最大载重为M。为了最小化运输趟数,请计算最少需要多少趟才能把所有货物运完?(假设货物不可拆分,每趟尽可能多装,但总重量不能超过M)

输入格式

第一行两个整数 n 和 M,分别表示货物批数和最大载重。

第二行 n 个整数,表示每批货物的重量。

输出格式

一个整数,表示最少趟数。

数据范围

1 ≤ n ≤ 1000,1 ≤ M ≤ 10000,1 ≤ w_i ≤ M。

样例

复制代码
输入:
5 10
2 5 4 7 1
输出:
3

(解释:可一趟装7+2=9,一趟装5+4=9,最后一趟装1,共3趟)


第2题(15分):"数字守艺人"数位黑洞------模拟

题目描述

任意给定一个四位数(数字不全相同),将数字按从大到小排列组成最大数,按从小到大排列组成最小数,用最大数减去最小数得到一个新数。重复这个过程,最终会进入一个循环(如6174黑洞)。

请编写程序,输出该四位数变换到第一次出现重复数字时,整个变换序列中不同数字的个数

输入格式

一个四位整数 x(1000 ≤ x ≤ 9999,且各位不全相同)。

输出格式

一个整数,表示序列中不同数字的个数。

样例

复制代码
输入:1234
输出:4

(解释:4321 - 1234 = 3087,8730 - 0378 = 8352,8532 - 2358 = 6174,7641 - 1467 = 6174。重复出现6174,序列为1234,3087,8352,6174,共4个,输出4)


第3题(20分):"智传民韵"纹样编码------字符串与递归

题目描述

壮锦纹样有一种编码规则:一个字符串可以按以下方式压缩------将连续重复的子串替换为"数字+子串"。例如:

  • "aaabbbcc" 可以压缩为 "3a3b2c"
  • "abcabcabc" 可以压缩为 "3abc"

现输入一个压缩后的字符串,请编写程序解压 还原原始字符串,并输出其长度。

(输入保证解压后的长度不超过100000)

输入格式

一行字符串,只包含小写字母和数字(数字为1-9)。

输出格式

两行,第一行为还原后的原始字符串,第二行为其长度。

样例

复制代码
输入:3a3b2c
输出:
aaabbbcc
8

第4题(20分):"长征路线"最长连续爬升天数------递推与贪心

题目描述

红军某部记录了连续n天的行军海拔高度。现需找出最长连续爬升的天数长度(即连续严格递增的子段长度,至少为1天)。

输入格式

第一行一个整数 n(1 ≤ n ≤ 100000)。

第二行 n 个整数,表示每天的海拔高度。

输出格式

一个整数,表示最长连续爬升天数。

样例

复制代码
输入:
6
3 1 2 3 5 4
输出:
4

(解释:最长连续递增子段为 1 2 3 5,长度4)



参考答案与解析
一、单选题答案与解析

第1题:答案 C

解析:a/b 执行的是整数除法,5/2 结果为2(截断小数部分),然后赋值给 double 类型的变量 c 时隐式转换为浮点数,所以 c 的值为 2.0。cout 输出 double 类型时默认不显示多余的小数末尾0,因此输出为 2。注意题目问"输出的结果",C选项为2.0,描述的是变量实际存储的值。

第2题:答案 B

解析:标准C++中,数组长度必须是编译期常量,不可以用变量定义。虽然某些编译器(如g++)支持变长数组(VLA)作为扩展,但这不是标准C++的规范,在正式竞赛中应视为错误写法。其他选项均为正确描述。

第3题:答案 B

解析:不使用记忆化的递归求解斐波那契数列,会产生大量重复计算,时间复杂度为O(2^n),n稍大(如n=50)就会导致运行时间急剧增加甚至超时。迭代、递推、记忆化数组都能将复杂度优化到O(n)。

第4题:答案 A

解析:判断字符是否在某个区间,必须使用逻辑与"&&"连接两个条件表达式。B选项使用了或"||"且缺少引号;C选项使用或"||"逻辑错误;D选项的连比写法在C++中不合法。

第5题:答案 B

解析:A错误,continue是跳过本次循环剩余语句,进入下一次迭代;B正确,break在嵌套循环中只能跳出当前最内层的一层循环;C错误,break也可用于循环语句;D错误,continue仅用于循环结构,不能用于switch。


二、多选题答案与解析

第6题:答案 AC

解析:C++标识符命名规则:只能由字母、数字、下划线组成,且不能以数字开头,不能与关键字重名。A选项以下划线开头合法;B选项以数字开头错误;C选项由字母组成合法;D选项是关键字,不能用作变量名。

第7题:答案 ABD

解析:A正确,vector是动态数组,支持通过下标随机访问;B正确,set底层是红黑树,自动去重并升序排列;C错误,map的键(key)是唯一的,不能重复,值(value)可以重复;D正确,pair是STL中用于组合两个值的工具。选错不得分。

第8题:答案 AC

解析:"以空间换时间"是指通过使用额外的存储空间来降低算法的时间复杂度。A桶排序需要额外数组统计频率;C记忆化搜索用数组存储已计算结果避免重复递归,都是典型应用。B递归求阶乘不涉及额外空间换取时间;D暴力枚举通常时间开销大,也不属于此范畴。

第9题:答案 ABC

解析:A正确,结构体成员可以是不同类型;B正确,同类型的结构体变量之间可以直接赋值(默认逐成员拷贝);C正确,结构体可作为参数传递(值传递或引用传递);D错误,结构体支持嵌套定义,即成员可以是另一个结构体类型。

第10题:答案 B

解析:程序功能是累加1到10中所有不是3的倍数的数。跳过3、6、9,累加 1+2+4+5+7+8+10 = 37。


三、编程题参考代码与解析
第1题:"丝路驼队"物资调度
思路分析

本题要求用最少的趟数运完所有货物,每趟载重不超过 M,货物不可拆分。

这是一个经典的双指针贪心问题:

  1. 先将所有货物重量从小到大排序
  2. 设置左指针 l 指向最轻的货物,右指针 r 指向最重的货物。
  3. 每次尝试让 最轻最重 的货物装在同一趟:
    • w[l] + w[r] <= M,说明能一起装,则 l++(轻的被带走),同时 r--(重的也被带走)。
    • 否则,说明最重的无法与当前最轻的一起装,则最重的只能单独 装一趟,只让 r--
    • 无论哪种情况,这一趟都运走了一些货物,趟数 ans++
  4. 重复直到 l > r,输出 ans

代码实现
cpp 复制代码
#include <bits/stdc++.h> 
using namespace std;

int w[1010]; //货物重量数组

int main() {
    int n, M;
    cin >> n >> M;
    for (int i = 1; i <= n; i++) cin >> w[i]; 

    sort(w + 1, w + n + 1); //升序排序

    int l = 1, r = n, ans = 0;
    while (l <= r) {
        if (w[l] + w[r] <= M) { //最轻和最重能同趟
            l++; //轻的带走
            r--; //重的也带走
        } else { //最重不能与当前最轻同趟
            r--; //最重的单独装一趟
        }
        ans++; //每趟计数
    }

    cout << ans;
    return 0;
}

第2题:"数字守艺人"数位黑洞
思路分析

本题模拟数字黑洞(6174)过程,要求输出第一次出现重复数字时,整个序列中不同数字的个数

操作步骤:

  1. 将当前四位数拆成四个数字,存入数组(下标1~4)。
  2. 将数组升序排列,得到最小数(注意前导0仍作为有效位,如0378即378,但计算时直接按四位数值处理即可,因为相减时会自动处理)。
  3. 将数组降序排列,得到最大数。
  4. 计算差值,作为下一个数。
  5. set<int> 记录所有出现过的数,每生成一个新数就尝试插入;若发现该数已在集合中,说明开始重复,停止循环。
  6. 输出集合的大小,即为不同数字的个数。

因为题目保证数字不全相同,且最多迭代次数很小(一般几十次),直接模拟即可。时间复杂度 O(常数)。


代码实现
cpp 复制代码
#include <bits/stdc++.h> 
using namespace std;

int d[5]; //存储四位数的各位数字,下标1~4

int nextNum(int x) { //计算下一个黑洞数
    for (int i = 1; i <= 4; i++) { //提取四位
        d[i] = x % 10;
        x /= 10;
    }
    sort(d + 1, d + 5); //升序排列(从小到大)
    int minNum = d[1] * 1000 + d[2] * 100 + d[3] * 10 + d[4]; //最小数
    int maxNum = d[4] * 1000 + d[3] * 100 + d[2] * 10 + d[1]; //最大数(降序)
    return maxNum - minNum;
}

int main() {
    int x;
    cin >> x;
    set<int> s; //记录已经出现的数
    while (s.find(x) == s.end()) { //当前数未出现过
        s.insert(x); //加入集合
        x = nextNum(x); //生成下一个
    }
    cout << s.size(); //集合大小即不同数字个数
    return 0;
}

第3题:"智传民韵"纹样编码
思路分析

本题是字符串解压问题,压缩规则为:数字 + 连续字母子串 ,表示将该子串重复数字次。

例如 "3abc""abcabcabc""3a3b2c""aaabbbcc"

解压方法是一次遍历输入字符串:

  1. 若当前字符是数字('0'~'9'),则完整解析出数字值。
  2. 然后向后提取连续的小写字母作为待重复的子串。
  3. 将该子串重复数字次,拼接到结果字符串中。
  4. 若当前字符是字母('a'~'z'),则直接拼接到结果。
  5. 遍历结束后,输出解压后的字符串及其长度。

代码实现
cpp 复制代码
#include <bits/stdc++.h> 
using namespace std;

int main() {
    string s, ans = "";
    cin >> s;
    int i = 0;
    while (i < s.size()) {
        if (s[i] >= '0' && s[i] <= '9') { //遇到数字,解析重复次数
            int num = 0;
            while (i < s.size() && s[i] >= '0' && s[i] <= '9') { //解析完整数字
                num = num * 10 + (s[i] - '0');
                i++;
            }
            string sub = "";
            while (i < s.size() && s[i] >= 'a' && s[i] <= 'z') { //提取数字后的连续字母子串
                sub += s[i];
                i++;
            }
            for (int k = 0; k < num; k++) { //重复拼接
                ans += sub;
            }
        } else { //直接是字母,原样拼接
            ans += s[i];
            i++;
        }
    }
    cout << ans << endl; //输出解压后的字符串
    cout << ans.size(); //输出长度
    return 0;
}

第4题:"长征路线"最长连续爬升天数
思路分析

本题求最长连续严格递增子段的长度,采用一次遍历即可:

  1. cur 记录当前连续递增子段的长度,初始为 1(至少包含第一天)。
  2. ans 记录全局最大长度,初始为 1。
  3. 从第 2 天开始遍历:
    • 若当前海拔 高于 前一天,则 cur++(连续递增延续)。
    • 否则,说明递增中断,更新 ans = max(ans, cur),并将 cur 重置为 1(当前这一天作为新子段的起点)。
  4. 遍历结束后,再更新一次 ans(处理整个序列一直递增的情况)。
  5. 输出 ans

代码实现
cpp 复制代码
#include <bits/stdc++.h> 
using namespace std;

int h[100010]; //海拔数组

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> h[i]; 

    int ans = 1; //至少为1天
    int cur = 1; //当前连续递增段长度
    for (int i = 2; i <= n; i++) { //从第二天开始比较
        if (h[i] > h[i - 1]) { //当前比前一天高,递增延续
            cur++;
        } else { //递增中断
            if (cur > ans) ans = cur; //更新最大值
            cur = 1; //重置为当前这一天
        }
    }
    if (cur > ans) ans = cur; //处理最后一段

    cout << ans;
    return 0;
}

关注老师的专栏,查看完整版全国青少年信息素养大赛C++备赛资料(初赛+复赛):

https://blog.csdn.net/weixin_66461496/category_12969975.html

相关课程《全国青少年信息素养大赛C++初赛真题试卷及答案解析》(视频课)

https://www.bilibili.com/cheese/play/ss447406764

相关课程《全国青少年信息素养大赛C++复赛真题试卷及答案解析》(视频课)

https://www.bilibili.com/cheese/play/ep2532538


各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:

https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:

https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:

https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:

https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

信奥赛C++普及组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):

https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):

https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
程序喵大人1 小时前
【C++进阶】STL容器与迭代器 - 10 把容器、迭代器和数据流串成一个小程序
开发语言·c++·容器·小程序·迭代器·stl
luj_17682 小时前
随机性在算法与占卜中的共通原理
c语言·开发语言·c++·经验分享·算法
Lazionr2 小时前
vector初识——从动态数组到STL核心容器
开发语言·c++
yyds_yyd_100862 小时前
3731. 找出缺失的元素(2026.08.04)
c++·leetcode
呱呱巨基2 小时前
CMake基础
linux·c++·笔记·学习
Tri_Function14 小时前
动态规划DP1(c++)
c++
清水迎朝阳17 小时前
客户端软件 — 用户统计方案
服务器·c++·客户端·用户统计
再卷也是菜18 小时前
C++17(下)
c++
alexwang21118 小时前
HDU 4348 详细题解
c++·算法·题解·hdu·主席树·可持久化数据结构·可持久化线段树