STL 指的是( )。
考点:STL 的概念(A1)。
(A1)考点:STL 的概念——C++ 标准模板库,提供现成函数与容器。
解析:本题考查 STL 的概念。STL 是「写好、测好、直接用」的标准组件库:函数有 min、max、swap、sort 等,容器有 vector、stack、queue、list 等。会用 STL 等于站在标准库的肩膀上写代码。
排除法:C 选新语言的人把它当成了独立语言——它是 C++ 的一部分;D 选第三方库的人低估了它的地位——「标准」二字就是官方内置;B 选排序算法的人把一个成员当成了全体。
竞赛代码常写 #include <bits/stdc++.h>,它的作用是( )。
考点:头文件与名字空间(A2)。
(A2)考点:头文件与名字空间——bits/stdc++.h 一次全含。
解析:本题考查头文件与名字空间。#include <bits/stdc++.h> 包含标准库全部头文件,竞赛中免去逐个 include;配套 using namespace std; 免去 std:: 前缀。正式工程不推荐(编译变慢),竞赛图快是惯例。
排除法:B 选只含输入输出的人把它当成了 iostream;D 选加速运行的人把编译期便利错当成了运行期加速;A 选必须配合 using 的人混淆了「包含」与「命名」两件事——不写 using 就要写 std::sort,头文件照样生效。
min(3, 7) 与 max(3, 7) 的值分别是( )。
考点:min 与 max 基础(A3)。
(A3)考点:min 与 max 基础——min(3,7)=3、max(3,7)=7。
解析:本题考查 min 与 max 基础。min 取两者较小、max 取较大,返回值可直接参与表达式。这两个函数是打擂台代码的标准替代。
排除法:C 答 与 的人把两个函数的功能对调;D 答 与 的人把 max 的功能记成了 min;A 答 与 的人自创了加减运算。
min(3, 7.5) 这样的调用(int 与 double 混合)在标准 C++ 中( )。
考点:min 与 max 的参数类型(A4)。
(A4)考点:min 与 max 的参数类型——两参数类型必须一致。
解析:本题考查 min 与 max 的参数类型。模板推导要求两个参数同类型:min(3, 7.5) 中 int 与 double 冲突,编译不通过;须写 min(3.0, 7.5) 或 min<double>(3, 7.5) 统一。这是模板函数的通用约束。
排除法:C 选自动取小数的人以为编译器会替你猜意图;D 选自动取整数的人同样把类型转换当成了自动魔法;A 选运行时崩溃的人把编译期类型检查错报成了运行期事故——错误在编译阶段就被拦下。
int a = 3, b = 7; swap(a, b); 执行后 a 与 b 的值是( )。
考点:swap 基础(A5)。
(A5)考点:swap 基础——两变量值互换。
解析:本题考查 swap 基础。swap(a, b) 把两个变量的值整体交换: 与 变 与 。它替代了「临时变量三行交换」的手写模板,且对容器、结构体等大对象同样适用。
排除法:D 答不变的以为只是看看;A 答变成相同值的人把交换错记成了赋值;B 答两次对调的人没执行真实语句。
数组 int a[4] = {5, 2, 9, 1}; 执行 sort(a, a + 4); 后,数组内容是( )。
考点:sort 基本用法(A6)。
(A6)考点:sort 基本用法——默认升序排列。
解析:本题考查 sort 基本用法。sort(a, a + 4) 把四个元素排成升序 1 2 5 9。一行调用替代整套手写排序,且平均 (B5 展开)。
排除法:A 答降序的人忘了默认从小到大;C 答 2 5 1 9 的人给的是某种中间状态——sort 完成后必是全序;B 答不变的人以为只是检查有序性。
sort(a, a + n) 排序的范围是( )。
考点:sort 的区间参数(A7)。
(A7)考点:sort 的区间参数——左闭右开 [a, a+n)。
解析:本题考查 sort 的区间参数。STL 普遍采用左闭右开区间:sort(a, a+n) 覆盖下标 到 恰 个元素;「尾后位置」a+n 是界标不参与排序。vector 写 sort(v.begin(), v.end()) 同理。
排除法:B 选 到 的人把右开记成了右闭、会多排一个越界位;D 选 到 的人把数学计数习惯带了进来、漏了首元素;A 选整个内存的人夸张失实。
不带第三个参数的 sort 默认按( )排列。
考点:sort 的默认次序(A8)。
(A8)考点:sort 的默认次序——默认升序。
解析:本题考查 sort 的默认次序。不带第三参数时 sort 用 < 比较,结果从小到大;要降序传 greater<int>()(B1)。字符串默认按字典序(B4)。
排除法:D 选降序的人把默认方向记反;A 选随机顺序的人把 sort 与随机混淆;C 选原序不变的人以为只是验证有序——sort 必定重排。
要把 int 数组按从大到小排序,最简洁的 STL 写法是( )。
考点:sort 降序写法(B1)。
(B1)考点:sort 降序写法——greater<int>() 一词搞定。
解析:本题考查 sort 降序写法。sort(a, a + n, greater<int>()) 用「大于」作比较,结果从大到小;与默认的 less<int>() 恰好镜像。也可写自定义 cmp(a,b){return a>b;}(08 卷已深入)。
排除法:A 选 less<int>() 的人拿到的是升序;D 选只能手工翻转的人不知道 greater 的存在;B 选传 的人把比较器参数当成了魔法数字。
int a[5] = {7, 3, 9, 1, 5}; 执行 sort(a + 1, a + 4); 后数组是( )。
考点:sort 部分区间(B2)。
(B2)考点:sort 部分区间——只排指定下标段。
解析:本题考查 sort 部分区间。sort(a+1, a+4) 只排下标 到 的 {3,9,1} 变 {1,3,9},首尾的 与 纹丝不动——输出 7 1 3 9 5。区间参数的灵活性让「局部排序」成为一行操作。
排除法:D 答全排 1 3 5 7 9 的人忽略了区间起止;B 答 7 1 3 5 9 的人把没参与的尾元素也排了位;A 答不变的人没执行区间排序。
按「个位数从小到大」给数组排序,sort 的第三个参数应传( )。
考点:sort 与自定义比较(B3)。
(B3)考点:sort 与自定义比较——cmp 函数定义次序规则。
解析:本题考查 sort 与自定义比较。sort 的第三个参数接收比较函数 cmp(a, b):返回真表示 应排在 前。按个位数排序就写 a % 10 < b % 10;比较函数与结构体排序的深入设计在 08 卷。
排除法:A 选 greater<int>() 的人只会整数值降序这一种规则;C 选传整数的人把比较器参数当成了数值;D 选不支持的人低估了 STL 的可扩展性。
字符串数组 {"banana", "apple", "cherry"} 执行默认 sort 后是( )。
考点:字符串排序(B4)。
(B4)考点:字符串排序——默认按字典序。
解析:本题考查字符串排序。字符串默认比较是字典序:逐字符比到第一个不同处定序,apple banana cherry 依次排好。前缀相同短者在前(如 app 排在 apple 前)。
排除法:B 答原顺序的人没执行排序;C 答按长度的人以为默认比 size——那要自定义比较器;A 答把 banana 换位的人按某种子序理解了字典序。
STL sort 对 个元素排序的平均时间复杂度是( )。
考点:sort 的复杂度(B5)。
(B5)考点:sort 的复杂度——平均 O(n log n)。
解析:本题考查 sort 的复杂度。STL sort 是混合排序(快排为骨架加插入与堆排兜底),平均 ;最坏也已被兜底保证在 级。百万级数据轻松应对。
排除法:B 答 的人把线性扫描的量级错安给排序;A 答 的人只记住了朴素快排的最坏;C 答 的人把二分查找的量级弄混。
「排序后元素带着原下标一起移动」要靠( )实现。
考点:排序后下标乱序(B6)。
(B6)考点:排序后下标乱序——要带旧下标须捆绑排序。
解析:本题考查排序后下标乱序。sort 只搬元素值,元素原来的位置信息随之丢失;要「值与原下标一起动」,把两者打包成 pair 或结构体按值排序即可——经典的「离散化、排名」预处理手段。
排除法:C 选自动保留的人没注意 sort 搬完即忘;A 选排序后再查找的人遇到重复值时旧下标无法区分;D 选无法实现的人低估了捆绑排序的威力。
关于 STL sort 的稳定性(相等元素的相对顺序),正确的是( )。
考点:排序稳定性关联(B7)。
(B7)考点:排序稳定性关联——sort 不保证稳定,双关键字补救。
解析:本题考查排序稳定性关联。相等元素在 sort 后的相对顺序无保证;要稳定效果,把「原下标」当第二关键字(值相同下标小者前)。稳定性的完整讨论在 08 卷。
排除法:B 选保证稳定的人高估了 STL sort——stable_sort 才保稳定(提高级视野);D 选取决于数组大小的人把偶然当规律;C 选天然稳定的人没见过相等元素被换位的实例。
向 vector<int> v; 尾部添加元素 的写法是( )。
考点:vector 定义与添加(C1)。
(C1)考点:vector 定义与添加——push_back 尾部追加。
解析:本题考查 vector 定义与添加。vector<int> v; 定义空动态数组,v.push_back(3) 在尾部追加 、size 自动加一。add 与 append 是别的语言的接口,C++ 统一叫 push_back。
排除法:A 填 add 的人把别的语言的习惯带进了 C++;D 填 append 的人同样错记了接口名——STL 只认 push_back;C 选下标赋值的人在空 vector 上直接越界写入是未定义行为。
vector 判断「当前没有任何元素」,标准写法是( )。
考点:size 与 empty(C2)。
(C2)考点:size 与 empty——empty() 判空最直接。
解析:本题考查 size 与 empty。v.empty() 返回是否为空,与 v.size() == 0 等价;循环与弹出操作前先判空是防越界的标准防线。vector 不与 NULL 比较(它不是指针)。
排除法:B 选 v == NULL 的人把指针判空的习惯错搬给容器对象;D 选 v[0] == 0 的人在空 vector 上就越界了;C 选 clear 的人把清空操作当成了判断操作。
vector 的下标访问 v[i]( )。
考点:下标访问(C3)。
(C3)考点:下标访问——O(1) 直达但无边界检查。
解析:本题考查下标访问。v[i] 与数组一样按位置直达 ;但越界是未定义行为(P1 展开),v.at(i) 才会检查并抛异常——竞赛为速度都用 v[i] 加自律的边界。
排除法:B 选 扫描的人把链表的代价错安给连续内存的 vector;C 选自动扩容的人把 push_back 的行为错安给了下标;D 选只读的人忘了下标也能赋值。
v.pop_back() 的作用是( )。
考点:尾部弹出(C4)。
(C4)考点:尾部弹出——pop_back 删尾不返回。
解析:本题考查尾部弹出。v.pop_back() 移除末元素、size 减一;要值先 v.back() 再 pop——与 stack/queue 的 pop 同一「只删不返」约定(P3、P6)。
排除法:B 选删除并返回的人把接口想得太贴心;C 选删开头的人把 vector 当成了队列;A 选清空全部的人把它当成了 clear。
v.clear() 执行后( )。
考点:clear 的效果(C5)。
(C5)考点:clear 的效果——size 归零通常不缩容量。
解析:本题考查 clear 的效果。v.clear() 移除全部元素、size 变 ,但已分配的内存一般保留(capacity 不变)——紧接着再 push_back 无需重新扩容,是「清空可复用」的设计。vector 对象本身没有被销毁。
排除法:B 选被销毁的人把 clear 当成了析构;A 选只删第一个的人把它当成了 pop_front(vector 没有此接口);C 选 size 不变的人无视了语义。
vector 区别于定长数组的核心特性是( )。
考点:动态增长的特性(C6)。
(C6)考点:动态增长的特性——按需自动扩容。
解析:本题考查动态增长的特性。push_back 在容量不足时自动申请更大内存、搬迁旧元素——使用者完全不必预估规模。定长数组赌小了装不下、赌大了浪费;vector 免去了这道心理负担。
排除法:A 选访问更快的人把增长能力错当速度优势;B 选不占内存的人违反物质守恒;D 选只能存整数的人忘了 vector<double>、vector<string> 都合法。
vector<int> v(n, 5); 的含义是( )。
考点:vector 的初始化(C7)。
(C7)考点:vector 的初始化——v(n, 5) 建 n 个 5。
解析:本题考查 vector 的初始化。vector<int> v(n, 5) 建长度 、全为 的 vector;v(n) 建长度 全 ;v = {1,2,3} 列表初始化。定长初始化后再下标赋值,是建「已知规模的表」的标准起手。
排除法:C 选容量 上限 的人把两个参数都错解了——前一个是元素个数、后一个才是初始值 ;A 选含 个元素每个是 的人把参数序弄反——那样实为 vector(5, n);B 选空 vector 的人忽略了初始化列表。
vector 与定长数组相比,说法正确的是( )。
考点:vector 与数组的对比(C8)。
(C8)考点:vector 与数组的对比——可变长可传值 vs 定长退化指针。
解析:本题考查 vector 与数组的对比。vector 长度可变、整体赋值与传值拷贝方便;数组定长、作函数参数退化为指针拿不到长度。竞赛里「个数未知」几乎必用 vector,定长够用则数组更轻量。
排除法:C 选数组支持 push_back 的人把 vector 的接口错安;D 选 vector 不能下标的人与 C3 矛盾;B 选完全等价的人忽略了两者的本质差异。
vector<int> v = {2, 5, 8}; 中 v.front() 与 v.back() 的值是( )。
考点:back 与 front 访问(D1)。
(D1)考点:back 与 front 访问——v={2,5,8} 的 front=2、back=8。
解析:本题考查 back 与 front 访问。v.front() 取首元素、v.back() 取末元素,与下标 v[0]、v[v.size()-1] 等价但更省字;对空 vector 调用它们同样是未定义行为。
排除法:C 答 与 的人把首尾语义对调;D 答 与 的人以为两者都取首;B 答 与 的人取了中间元素的位置。
vector<vector<int>> g(n); 常用来( )。
考点:二维 vector(D2)。
(D2)考点:二维 vector——vector<vector<int>> 建可变行。
解析:本题考查二维 vector。vector<vector<int>> g(n) 建 个可变长度的行,各行独立 push_back——正是邻接表存图的标准形态(06 卷已实战)。与定长 int g[N][M] 不同,每行长度可各自生长。
排除法:A 选 定长矩阵的人把它当成了二维数组;C 选存字符串的人类型搞错;B 选替代一维且更快的人没有速度优势只有结构优势。
vector<Node> v; 存自定义结构体并 push_back(t),关于这种用法( )。
考点:vector 存结构体(D3)。
(D3)考点:vector 存结构体——结构体整体进出容器。
解析:本题考查 vector 存结构体。vector<Node> 把每个结构体当作不可分割的元素存取:push_back 整体压入、下标整体访问、sort 时按任意成员写比较函数(08 卷结构体排序)。
排除法:C 选不能进 vector 的人低估了模板的通用性;A 选逐成员分开存的人放弃了一体化管理的便利;D 选只能存一个的人把 vector 当成了单变量。
函数要修改调用方的 vector 内容,形参应写成( )。
考点:vector 作函数参数(D4)。
(D4)考点:vector 作函数参数——修改原容器须引用传递。
解析:本题考查 vector 作函数参数。值传递 f(vector<int> v) 拷贝整个容器、修改不影响调用方;要修改原容器用引用 f(vector<int>& v),还省去拷贝开销。这与「数组传参天然作用原数据」的旧习惯不同。
排除法:A 选值传递的人改的只是副本;D 选指针数组混合写法的人语法不通;C 选不能作参数的人低估了 C++ 的参数能力。
无向图加边 (u, v) 用 vector 边表的标准动作是( )。
考点:边表存图应用(D5)。
(D5)考点:边表存图应用——无向边两个方向都挂。
解析:本题考查边表存图应用。g[u].push_back(v) 与 g[v].push_back(u) 两条都要写——无向边从两端看各是一条出边;漏写反向边,逆方向的遍历就失明(06 卷的教训)。vector 边表配合 range-for 遍历是图论代码的标配。
排除法:D 选只加一条的人把有向边的写法错用到无向图;C 选开邻接矩阵的人混了两种存法(矩阵与 vector 边表各有适用场景);B 选不能存图的人没用过 vector<vector<int>>。
遍历 vector<int> v 求和,初赛最常用的写法是( )。
考点:vector 的遍历方式(D6)。
(D6)考点:vector 的遍历方式——下标循环边界用 v.size()。
解析:本题考查 vector 的遍历方式。下标 for 上界写 (int)v.size():size 返回无符号数,与负数比较会出隐式转换坑,初赛习惯显式转 int。range-for(for (int x : v))是 C++11 起的等价写法(G6)。
排除法:D 选上界取到 size 的人会把 v[size()] 的越界位也带上;A 选 while(v[i]) 的人拿值当条件碰上 就断;C 选无法遍历的人没写过任何 vector 代码。
定义整型栈并压入 的写法是( )。
考点:stack 定义与入栈(E1)。
(E1)考点:stack 定义与入栈——stack<int> 与 push。
解析:本题考查 stack 定义与入栈。stack<int> st; 定义整型栈,st.push(5) 压入。模板参数 <int> 必写(B 选项省略不合法);接口是 push 不是 add。栈的原理与手写实现已在 05 卷深入。
排除法:A 选省略模板参数的人写不通过编译;C 选 int stack 的人把类型关键字当成了容器;B 选 add 的人把别的库接口错安给 STL。
st.top() 的作用是( )。
考点:top 的语义(E2)。
(E2)考点:top 的语义——只看不删。
解析:本题考查 top 的语义。st.top() 返回栈顶元素的引用副本,栈内元素不变;连看多次 top() 值不变。「先看后删」拆成 top 与 pop 两步是 STL 的设计哲学。
排除法:A 选返回并删除的人把 top 与 pop 合并想象;C 选返回栈底的人方向全反;D 选返回大小的人把 size 的功能错安。
st.pop() 的行为是( )。
考点:pop 只删不返(E3)。
(E3)考点:pop 只删不返——要值先 top 再 pop。
解析:本题考查 pop 只删不返。st.pop() 仅移除栈顶、无返回值;int x = st.pop(); 编译不过(P3)。正确姿势两步走:int x = st.top(); st.pop();。
排除法:A 选删除并返回的人给 pop 加了不存在的返回;B 选只返回不删除的人把 top 的语义错安;D 选清空整个栈的人把它当成了清仓操作。
弹出循环 while (!st.empty()) { ... st.pop(); } 中 empty() 的作用是( )。
考点:empty 判空(E4)。
(E4)考点:empty 判空——弹出循环的护栏。
解析:本题考查 empty 判空。while (!st.empty()) 保证循环体内 top/pop 作用在非空栈上——对空栈 pop 或 top 是未定义行为(P2)。判空是所有容器弹出操作的第一道防线。
排除法:C 选清空栈的人把判断当成了操作;B 选统计个数的人把 empty 与 size 混为一谈;A 选装饰的人低估了未定义行为的杀伤力。
st.size() 返回( )。
考点:size 计数(E5)。
(E5)考点:size 计数——返回当前元素个数。
解析:本题考查 size 计数。st.size() 是「现在栈里有几个」,随 push 增、pop 减;它不是容量上限(容器无固定上限概念),也不是栈顶的值。
排除法:D 选容量上限的人把 size 记成了预留空间;B 选栈顶值的人把两个接口混同;C 选永远返回 的人大概只测过空栈。
依次 push 后连续 pop 两次,弹出的元素依次是( )。
考点:后进先出的体现(E6)。
(E6)考点:后进先出的体现——push 1,2,3 后 pop 得 3,2。
解析:本题考查后进先出的体现。压入 后栈顶是 :第一次 pop 出 ,第二次 pop 出 ——最后的进、最先的出。这一性质使栈天然适合「最近的先处理」(H2)。
排除法:A 答 与 的人按先进先出理解了栈;D 答 与 的人第一发对了第二发跳层;B 答 与 的人把两端各取了一个。
要按「从顶到底」的顺序处理栈中所有元素,标准做法是( )。
考点:stack 遍历须弹出(E7)。
(E7)考点:stack 遍历须弹出——stack 不支持下标与顺序遍历。
解析:本题考查 stack 遍历须弹出。stack 刻意只暴露顶端:要看遍全部只能「top 处理后 pop」循环,处理完栈也空了。要看但不破坏,只能把元素倒进别的容器。这是「接口受限保护语义」的设计。
排除法:B 选下标遍历的人把 vector 的能力错安给 stack;C 选排序后再看的人破坏了栈还未必达意;D 选无法访问任何元素的人忘了 top 的存在。
定义整型队列并把 加入队尾的写法是( )。
考点:queue 定义与入队(F1)。
(F1)考点:queue 定义与入队——queue<int> 与 push 入队尾。
解析:本题考查 queue 定义与入队。queue<int> q; q.push(4); 把 排到队尾。queue 没有 push_back 这个名字——统一叫 push;insert 是别的容器的接口。
排除法:C 选 push_back 的人把 vector 的接口错安给 queue;A 选省略模板参数的人编译不过;D 选 insert 的人接口张冠李戴。
queue<int> q 依次入队 后,q.front() 与 q.back() 是( )。
考点:front 与 back(F2)。
(F2)考点:front 与 back——队头最早、队尾最晚。
解析:本题考查 front 与 back。入队 后:front() 是最早进来的 、back() 是最晚进来的 。两端都可看不可删(删除走 pop)。
排除法:A 答 与 的人把首尾对调;D 答 与 的人以为两端同值;C 答 与 的人取了中间。
队列的 pop() 从哪一端删除元素( )。
考点:pop 从队头删(F3)。
(F3)考点:pop 从队头删——与 stack 的弹出位置不同。
解析:本题考查 pop 从队头删。queue 的 pop() 移除的是 front 端(最早进入的)元素——与 stack 从顶端弹形成对照;两端语义相反正是两种抽象的分野。
排除法:B 选队尾的人把栈的弹出位置错安给队列;A 选中间的人队列没有中间操作;D 选随机位置的人把队列当成了随机结构。
队列「先进先出」的进出规则是( )。
考点:队尾进队头出(F4)。
(F4)考点:队尾进队头出——先进先出的实现路径。
解析:本题考查队尾进队头出。队列的数据流向单向:push 从 back 进、pop 从 front 出——像现实排队,先来先服务。若两端都能随意进出就不再是有界语义的队列。
排除法:C 选队头进队尾出的人方向整体反了;D 选两端随意的人描述的是双端队列 deque(提高级);B 选只能进不能出的人忘了 pop 的存在。
要拿到队头元素的值并让它出队,正确顺序是( )。
考点:先取后弹的顺序(F5)。
(F5)考点:先取后弹的顺序——pop 不返回值,弹完取不到。
解析:本题考查先取后弹的顺序。int x = q.front(); q.pop(); 是标准两步;反过来先 pop 再 front 拿到的是下一个元素,而 x = q.pop() 编译不过。顺序颠倒是常见笔误的来源。
排除法:D 选先 pop 再 front 的人丢掉了原本要处理的队头;B 选一步到位的人给 pop 虚构了返回值;A 选顺序随意的人没踩过顺序坑。
队列当前元素个数用( )获取。
考点:size 与 empty(F6)。
(F6)考点:size 与 empty——个数是 size 不是 length。
解析:本题考查 size 与 empty。queue 取个数用 q.size()——length 与 count 是其它语言的接口;sizeof(q) 是对象字节数与元素个数无关。判空用 q.empty()。
排除法:B 选 length 的人把 Java/Python 习惯带了过来;C 选 count 的人同样错库;D 选 sizeof 的人把编译期字节数当成了运行期计数。
按出队顺序处理队列全部元素并清空它,标准循环是( )。
考点:queue 遍历须弹出(F7)。
(F7)考点:queue 遍历须弹出——处理全部并清空的标准循环。
解析:本题考查 queue 遍历须弹出。queue 也不支持下标:while (!q.empty()) { 处理 q.front(); q.pop(); } 是边处理边清空的标准形态;BFS 正是靠这个循环把待访问层逐个展开(L5)。要保留原队列得先拷贝。
排除法:C 选下标循环的人又把 vector 的能力错安;D 选 while (q) 的人把容器当成了布尔值;A 选只能看一个的人忘了 pop 之后 front 会自动变成下一个——遍历能力是完整的。
list<int> L; 要在头部与尾部各插一个元素,正确的两个接口是( )。
考点:list 定义与两端插(G1)。
(G1)考点:list 定义与两端插——push_front 与 push_back。
解析:本题考查 list 定义与两端插。list<int> L; 是 STL 的链表容器(原理在 16 卷):push_front 头插、push_back 尾插,两端都是 。insert_front 与 append 不是 STL 接口。
排除法:D 选自造接口的人把别的语言词汇错安;B 选下标赋值的人忘了 list 不支持下标(G5);C 选只能尾插的人低估了双向链表的双端能力。
list<int> L 依次 push_back(2)、push_front(1)、push_back(3) 后,L.front() 与 L.back() 是( )。
考点:front 与 back 访问(G2)。
(G2)考点:front 与 back 访问——{1,2,3} 首 1 尾 3。
解析:本题考查 front 与 back 访问。依次 push_back(2)、push_front(1)、push_back(3) 后链上为 :front() 是 、back() 是 。M1 是它的代码形态。
排除法:D 答 与 的人把首尾对调;C 答 与 的人没追上头插的效果;B 答 与 的人漏了末尾的 。
L.pop_front() 与 L.pop_back() 分别删除( )。
考点:两端弹出(G3)。
(G3)考点:两端弹出——pop_front 删首、pop_back 删末,都不返回值。
解析:本题考查两端弹出。pop_front() 与 pop_back() 分别移除首末元素,均只删不返——与 stack/queue/vector 的 pop 系列同一约定,「取值另配 front/back」。
排除法:D 选末与首的人把两个接口对调;C 选两个都删首的人以为 pop 系列都是头删;A 选删除并返回的人给接口虚构了返回值。
list 与 vector 最关键的对比是( )。
考点:list 与 vector 的对比(G4)。
(G4)考点:list 与 vector 的对比——随机访问 vs 双端高效。
解析:本题考查 list 与 vector 的对比。vector 连续内存:下标 、尾部增删快、中间插删要搬移;list 链式结构:两端增删都 、但不支持下标、遍历只能顺链走。按「要不要随机访问」选型。
排除法:A 选接口完全相同的人没发现 list 连 [] 都没有;B 选 list 访问更快的人方向全反——随机访问恰恰是 list 的短板;D 选 vector 不能遍历的人没用过 range-for。
L[2] 对 list 而言( )。
考点:list 不支持下标(G5)。
(G5)考点:list 不支持下标——L[2] 编译不过。
解析:本题考查 list 不支持下标。链式结构没有「第 k 个在哪」的直接答案,要走到第 个得顺链数 步——所以 STL 干脆不给 list 下标接口,L[2] 直接编译错误。随机访问的需求请交给 vector。
排除法:C 选正常取第三个的人把 vector 的能力错安;B 选自动走到第三个的人高估了接口的贴心程度;A 选返回队头的人接口语义全错。
C++11 起遍历 list<int> L 最简洁的写法是( )。
考点:range-for 遍历(G6)。
(G6)考点:range-for 遍历——for (int x : L) 逐元素访问。
解析:本题考查 range-for 遍历。C++11 的范围 for for (int x : L) 让容器依次「吐出」元素,list 与 vector 通用;底层是迭代器(提高级概念,初赛会用即可,大纲未明列)。它解决了 list 无下标的遍历难题。
排除法:D 选下标循环的人在 list 上编译不过;A 选直接输出容器的人 C++ 没有这种重载;C 选无法遍历的人低估了 range-for 的普适性。
「需要下标随机访问、且只在尾部增删」应选( )。
考点:四容器的选择(H1)。
(H1)考点:四容器的选择——要随机访问选 vector。
解析:本题考查四容器的选择。「下标随机访问 + 只尾部增删」是 vector 的精确画像:stack 只开放顶端、queue 只开放两端语义受限、list 无下标。需求里有 v[i] 基本就锁定了 vector。
排除法:D 选 list 的人拿不到下标;C 选 stack 的人只有 top 没有随机访问;B 选 queue 的人只有 front/back 可看。
下列最适合用 stack 的场景是( )。
考点:栈的典型场景(H2)。
(H2)考点:栈的典型场景——最近的先处理。
解析:本题考查栈的典型场景。括号匹配(右括号配最近的左括号)、表达式求值(最近的操作数先算)、撤销回退(最近的操作先撤)——共性是「后发生的先处理」,即 LIFO。排队打印、随机查成绩、名单按序取都不需要这个性质。
排除法:C 选排队打印的人那是队列场景(H3);B 选随机查成绩的人需要下标访问(H4);A 选按序号取名单的人同样是 vector 场景。
下列最适合用 queue 的场景是( )。
考点:队列的典型场景(H3)。
(H3)考点:队列的典型场景——先来先服务。
解析:本题考查队列的典型场景。BFS 的待访问列表(先发现先扩展)、打印队列(先提交先打印)——共性是「公平按序」,即 FIFO。括号匹配要最近性、随机访问要下标、双端频繁插删是 list。
排除法:C 选括号匹配的人选了栈的场景;B 选频繁访问中间的人没有容器能高效满足这种伪需求;D 选两端插删的人那是 list 的场景(H5)。
下列最适合用 vector 的场景是( )。
考点:vector 的典型场景(H4)。
(H4)考点:vector 的典型场景——个数未知先收集后排序。
解析:本题考查 vector 的典型场景。「读入个数未知的序列,之后排序与下标访问」是 vector 的教科书场景:动态收集 push_back、sort 一排、下标随便用。三个错误选项分别是 stack/queue/list 的场景画像。
排除法:A 选只处理最近一个的人是栈;B 选先进先出排队的人是队列;D 选只在头部插删的人没有这种容器(vector 头插要整体搬移)。
下列最适合用 list 的场景是( )。
考点:list 的典型场景(H5)。
(H5)考点:list 的典型场景——两端频繁插删、不需随机访问。
解析:本题考查 list 的典型场景。两端进出频繁、且从不按下标找元素——list 的双端 优势才能兑现;若还要频繁二分或随机访问,list 的短板立刻暴露。
排除法:D 选频繁二分的人没有下标连二分的 mid 都取不到;A 选只访问末尾的人一个 vector 就够;C 选必须有序的人把「保持有序」当成了 list 的职责——顺序结构才管有序性。
初赛中 STL 容器与手写数组实现的取舍,正确的态度是( )。
考点:STL 与手写的取舍(H6)。
(H6)考点:STL 与手写的取舍——优先 STL,手写为理解。
解析:本题考查 STL 与手写的取舍。STL 接口标准、边界行为明确、久经测试,初赛优先使用;手写数组栈/队列的价值在于理解原理(05 卷的手写训练)与极端性能定制。两者不是对立而是层次不同。
排除法:B 选 STL 太慢永远不用的人夸大了开销——多数题目 STL 足够快;D 选手写无价值的人否定了原理学习的意义;A 选接口相同随便选的人忽略了维护成本与易错性的差异。
01int a = 3, b = 7; 02cout << min(a, b) << " " << max(a, b);
输出是( )。
考点:min 与 max 执行(I1)。
(I1)考点:min 与 max 执行——min(3,7)=3、max(3,7)=7。
解析:本题考查 min 与 max 执行。直接调用输出 3 7。I 组的代码题都是单行函数的直读,热身定位。
排除法:A 答 7 3 的人把两个函数对调;D 答 3 3 的人 max 失效;B 答 10 4 的人自创加减。
01int a = 3, b = 7, c = 5; 02cout << min(a, max(b, c));
输出是( )。
考点:嵌套 min 与 max(I2)。
(I2)考点:嵌套 min 与 max——min(3, max(7,5))=3。
解析:本题考查嵌套 min 与 max。先算内层 max(7,5)=7,再算 min(3,7)=3。嵌套组合能实现三数取中(max(min(a,b), min(max(a,b), c)))等技巧。
排除法:A 答 的人外层 min 没生效;C 答 的人内层取了小值;D 答 的人把求和当成了比较。
01int a = 3, b = 7; 02swap(a, b); 03cout << a << " " << b;
输出是( )。
考点:swap 执行(I3)。
(I3)考点:swap 执行——3 与 7 互换得 7 3。
解析:本题考查 swap 执行。swap(a, b) 后 、,输出 7 3。不需要手写临时变量。
排除法:A 答 3 7 的人以为只是比较;B 答 7 7 的人把交换错记成了赋值单向;D 答 3 3 的人方向又反。
01int a[] = {5, 2, 9, 1}; 02sort(a, a + 4); 03for (int i = 0; i < 4; i++) cout << a[i];
输出是( )。
考点:sort 升序执行(I4)。
(I4)考点:sort 升序执行——{5,2,9,1} 排成 1259。
解析:本题考查 sort 升序执行。默认升序把 排成 ,输出 1259。验算脚本实测一致。
排除法:B 答 9521 的人默认方向记反;A 答 2519 的人给的是中间状态;D 答 1295 的人最后两位序错。
01int a[] = {5, 2, 9, 1}; 02sort(a, a + 4, greater<int>()); 03for (int i = 0; i < 4; i++) cout << a[i];
输出是( )。
考点:sort 降序执行(I5)。
(I5)考点:sort 降序执行——greater 得 9521。
解析:本题考查 sort 降序执行。greater<int>() 让大的在前:,输出 9521。与 I4 同数据镜像。
排除法:C 答 1259 的人忘了传比较器;B 答 9125 的人只对了首元素;D 答 5219 的人部分排序错。
01int a[] = {7, 3, 9, 1, 5}; 02sort(a + 1, a + 4); 03for (int i = 0; i < 5; i++) cout << a[i];
输出是( )。
考点:sort 部分区间执行(I6)。
(I6)考点:sort 部分区间执行——只排 [1,4) 得 71395。
解析:本题考查 sort 部分区间执行。sort(a+1, a+4) 只动下标 ~ 的 变 :输出 7 1 3 9 5 连起来 71395。区间外元素原地不动。
排除法:C 答 13579 的人全排了;A 答 73195 的人区间没排或没生效;D 答 13795 的人区间内排序结果错。
01vector<int> v; 02v.push_back(3); v.push_back(1); v.push_back(4); 03for (int i = 0; i < (int)v.size(); i++) cout << v[i]; 04cout << " " << v.size();
输出是( )。
考点:push_back 序列(J1)。
(J1)考点:push_back 序列——3 1 4 依次入尾。
解析:本题考查 push_back 序列。依次 push_back :内容 3 1 4(保持入序)、size 为 ,输出 314 3。
排除法:A 答 134 3 的人把内容顺手排了序——push 不排序;C 答 314 4 的人 size 数错;B 答 3 1 的人漏了第三个元素。
01vector<int> v; 02v.push_back(3); v.push_back(1); v.push_back(4); 03v.pop_back(); 04for (int i = 0; i < (int)v.size(); i++) cout << v[i]; 05cout << " " << v.size();
输出是( )。
考点:pop_back 与大小(J2)。
(J2)考点:pop_back 与大小——弹掉 4 后 31、size 2。
解析:本题考查 pop_back 与大小。pop_back 移除末尾的 :内容变 3 1、size 从 变 ,输出 31 2。
排除法:D 答 314 2 的人以为只减 size 不删元素;B 答 31 3 的人 size 没跟着减;A 答 14 2 的人删错了端。
01vector<int> v; 02v.push_back(3); v.push_back(1); 03v[0] = 9; 04for (int i = 0; i < (int)v.size(); i++) cout << v[i];
输出是( )。
考点:下标修改(J3)。
(J3)考点:下标修改——v[0]=9 改首元素。
解析:本题考查下标修改。v[0] = 9 把首个 改成 :内容变 9 1。下标既可读也可写,与数组一致。
排除法:C 答 31 的人以为 vector 不可改;A 答 93 的人把第二个元素也动了;B 答 99 的人以为会把全部改成 。
01vector<int> v; 02v.push_back(9); v.push_back(1); 03int s = 0; 04for (int i = 0; i < (int)v.size(); i++) s += v[i]; 05cout << s;
输出是( )。
考点:遍历求和(J4)。
(J4)考点:遍历求和——9+1=10。
解析:本题考查遍历求和。下标循环累加 。上界 (int)v.size() 的写法(D6)在此体现。
排除法:A 答 的人把两个数字拼成了两位数;B 答 的人循环只跑了一轮;C 答 的人只加了末元素。
01vector<int> v; 02v.push_back(9); v.push_back(1); 03for (int i = (int)v.size() - 1; i >= 0; i--) cout << v[i];
输出是( )。
考点:逆序输出(J5)。
(J5)考点:逆序输出——下标从尾到头。
解析:本题考查逆序输出。循环从 v.size()-1 递减到 : 逆序输出 19。逆序访问是下标循环的基操。
排除法:D 答 91 的人方向没反;A 答 98 的人内容记错;B 答 11 的人以为逆序是复制末元素。
01vector<int> v; 02v.push_back(9); v.push_back(1); 03v.push_back(7); v.push_back(2); 04sort(v.begin(), v.end()); 05for (int x : v) cout << x;
输出是( )。
考点:push 后排序(J6)。
(J6)考点:push 后排序——9 1 7 2 排成 1279。
解析:本题考查 push 后排序。sort(v.begin(), v.end()) 对 vector 整体升序: 变 ,输出 1279。begin/end 是 vector 版的「区间参数」。
排除法:A 答 9172 的人没排;D 答 1297 的人排序结果错;B 答 7912 的人排成了某种错位序。
01vector<int> v; 02for (int x : {1, 2, 7, 9}) v.push_back(x); 03while (!v.empty()) { cout << v.back(); v.pop_back(); }
输出是( )。
考点:尾部弹空(J7)。
(J7)考点:尾部弹空——back 配 pop_back 逆序清空。
解析:本题考查尾部弹空。while (!v.empty()) 循环:先 cout << v.back() 再 pop_back()——输出 即 9721,结束后 size 为 。vector 也能这样当栈用。
排除法:D 答 1279 的人从首端取了——back 取的是尾;B 选 1279 然后崩溃的人以为会越界——判空循环安全收尾;C 答 9 的人只弹了一次。
01stack<int> st; 02st.push(1); st.push(2); st.push(3); 03cout << st.top();
输出是( )。
考点:top 追踪(K1)。
(K1)考点:top 追踪——压 1,2,3 后 top 是 3。
解析:本题考查 top 追踪。三次 push 后栈顶是最后压入的 ——LIFO 的直接验证。
排除法:B 答 的人以为栈顶是最早的;C 答 的人取了中间;A 答 的人把求和当 top。
01stack<char> sc; 02string s = "abcde"; 03for (char c : s) sc.push(c); 04string r; 05while (!sc.empty()) { r += sc.top(); sc.pop(); } 06cout << r;
输出是( )。
考点:栈翻转字符串(K2)。
(K2)考点:栈翻转字符串——abcde 变 edcba。
解析:本题考查栈翻转字符串。全部入栈后逐个弹出:,得 edcba。栈是「逆序器」的经典应用。
排除法:C 答 abcde 的人以为栈保序;B 答 aedcb 的人首尾对调只做了一半;A 答空串的人没看到 r 在累积。
01string t = "{[()]}"; 02stack<char> st; 03bool ok = true; 04for (char c : t) { 05 if (c == '(' || c == '[' || c == '{') st.push(c); 06 else { 07 char o = st.top(); st.pop(); 08 if ((c == ')' && o != '(') || (c == ']' && o != '[') || (c == '}' && o != '{')) ok = false; 09 } 10} 11cout << (ok && st.empty() ? 1 : 0);
输出是( )。
考点:括号匹配执行(K3)。
(K3)考点:括号匹配执行——{[()]} 完全嵌套匹配输出 1。
解析:本题考查括号匹配执行。左括号依次入栈:{、[、(;遇右括号逐层弹栈比对——) 配 (、] 配 [、} 配 {,全程吻合且栈终空,输出 。嵌套括号恰是 LIFO 结构的对口场景。
排除法:D 答 的人没逐层比对就下结论;A 答 的人输出了字符数;B 选崩溃的人没看懂序列合法——右括号出现时栈从不为空。
栈空开始依次执行:push(1)、push(2)、pop 并输出栈顶、push(3)、pop 并输出、pop 并输出。输出的三个数依次是( )。
考点:进出栈混合作业(K4)。
(K4)考点:进出栈混合作业——push1,push2,pop,push3,pop,pop 得 2 3 1。
解析:本题考查进出栈混合作业。第一步后栈内 ,pop 出 ;压入 后 pop 出 ;最后 pop 出 。输出 ——操作序列逐态追踪是栈代码题的基本功。
排除法:B 答 的人按入序输出没管栈序;D 答 的人后两次 pop 对调;A 答 的人以为全部入完再出。
01stack<int> st; 02st.push(5); st.push(2); st.push(8); 03while (!st.empty()) { cout << st.top(); st.pop(); }
输出是( )。
考点:全部弹出(K5)。
(K5)考点:全部弹出——825 从顶到底。
解析:本题考查全部弹出。栈内自底向上 ,全部弹出从顶开始:,输出 825。判空循环保证安全清空。
排除法:C 答 528 的人从栈底开始;A 答 258 的人取了中间层序;B 答 852 的人首对尾错。
依次进栈(进栈顺序固定,可在任意时刻出栈),下列哪个出栈序列不可能( )。
考点:出栈合法性判断(K6)。
(K6)考点:出栈合法性判断——3 1 2 不可能。
解析:本题考查出栈合法性判断。 最先出栈说明 已全部入栈且 在 上方;接下来只能先出 再出 ——3 1 2 中 抢在 前违背栈结构。其余三个序列都能构造出合法操作序。
排除法:A 选 1 2 3 的人误以为入一个出一个才合法——边入边出正是它;D 选 2 1 3 的人没验证 出后 立即出的合法性;B 选 3 2 1 的人没看出全入再全出就是它。
01queue<int> q; 02q.push(1); q.push(2); q.push(3); 03cout << q.front() << " " << q.back();
输出是( )。
考点:front 与 back 追踪(L1)。
(L1)考点:front 与 back 追踪——入 1,2,3 后 front 1 back 3。
解析:本题考查 front 与 back 追踪。 最早入队在头、 最晚在尾:输出 1 3。两端只看不删。
排除法:B 答 3 1 的人首尾对调;C 答 1 1 的人以为两端同看队头;A 答 2 2 的人取了中间。
01queue<int> q; 02q.push(1); q.push(2); q.push(3); 03q.pop(); 04cout << q.front();
输出是( )。
考点:pop 后 front(L2)。
(L2)考点:pop 后 front——弹出 1 后 front 变 2。
解析:本题考查 pop 后 front。q.pop() 移除队头的 ,front 自动变成下一个 。弹出后 front 的「自动前移」是队列操作的核心画面。
排除法:C 答 的人以为 pop 不影响 front;D 答 的人跳过了 ;B 答 的人以为弹出后空。
01queue<int> q; 02q.push(1); q.push(2); q.push(3); 03q.pop(); 04while (!q.empty()) { cout << q.front(); q.pop(); }
输出是( )。
考点:全部出队(L3)。
(L3)考点:全部出队——先弹 1 再全出得 23。
解析:本题考查全部出队。先 pop 掉 ,队列剩 ;while 循环依次出队输出 23。
排除法:C 答 123 的人忘了先弹过一次;D 答 32 的人逆序了队列;A 答 3 的人少出了一次。
01queue<int> q; 02for (int i = 1; i <= 5; i++) q.push(i); 03int cnt = 0; 04while (!q.empty()) { 05 cnt++; 06 int x = q.front(); q.pop(); 07 if (cnt % 3 == 0) cout << x << " "; 08 else q.push(x); 09}
输出是( )。
考点:约瑟夫队列模拟(L4)。
(L4)考点:约瑟夫队列模拟——报 3 出列得 3 1 5 2 4。
解析:本题考查约瑟夫队列模拟。计数出列再入队队尾模拟「围圈报数」:出列序 (与 16 卷循环链表版完全一致——两种容器殊途同归)。队列模拟是约瑟夫的无指针实现法。
排除法:D 答 3 4 5 1 2 的人把出列当成了顺序跳过;C 答 1 2 3 4 5 的人没做报数;B 选死循环的人没注意出列者不再入队、队列必然清空。
图: 连向 ; 连向 。从 出发 BFS(入队即标记),队列逐个出队访问。访问顺序是( )。
考点:BFS 队列模拟(L5)。
(L5)考点:BFS 队列模拟——访问序 1 2 3 4。
解析:本题考查 BFS 队列模拟。 出队时把邻点 依次入队; 出队把 入队;随后 依次出队——访问序 1 2 3 4。「出队访问、邻点入队」的循环正是 BFS 骨架(06 卷已深入)。
排除法:C 答 1 2 4 3 的人把 提前到 前—— 是 的孩子晚于 出队;B 答 1 3 2 4 的人邻点入队序反了;A 答 1 4 2 3 的人层次混乱。
队列 q = {4, 7}(队头 ),执行:出队 、 加 后重新入队,共两次。最终队列(从队头到队尾)是( )。
考点:轮流出队入队(L6)。
(L6)考点:轮流出队入队——两次「出队加一回队」得 5 8。
解析:本题考查轮流出队入队。第一次: 出队、变 入队,队列 ;第二次: 出队、变 入队,队列 。出队入队的对象要逐轮追踪。
排除法:B 答 4 5 8 的人以为原队头 还在;D 答 4 7 的人一次也没执行;C 答 8 5 的人把队序反了。
01queue<int> q; 02q.push(6); 03while (!q.empty()) q.pop(); 04cout << q.size();
输出是( )。
考点:队列判空弹出(L7)。
(L7)考点:队列判空弹出——弹空后 size 为 0。
解析:本题考查队列判空弹出。while (!q.empty()) q.pop(); 把唯一的 弹出后 empty 成立、循环终止,size 归 。判空条件保证不多弹一次。
排除法:A 答 的人以为弹出不影响 size;C 答 的人把元素值当成了 size;B 选崩溃的人没注意判空护栏的存在。
01list<int> L; 02L.push_back(2); L.push_front(1); L.push_back(3); 03for (int x : L) cout << x; 04cout << " " << L.front() << " " << L.back();
输出是( )。
考点:两端插入(M1)。
(M1)考点:两端插入——push_back(2)、push_front(1)、push_back(3) 得 1 2 3。
解析:本题考查两端插入。尾插 后链上 ;头插 变 ;再尾插 变 。输出内容 123 且 front 、back 。
排除法:A 答 123 3 1 的人首尾对调;C 答 213 的人头插的位置错;D 答 321 的人把三个操作全当成了头插。
01list<int> L; 02L.push_back(1); L.push_back(2); L.push_back(3); 03L.pop_front(); L.pop_back(); 04for (int x : L) cout << x;
输出是( )。
考点:两端弹出(M2)。
(M2)考点:两端弹出——pop_front 与 pop_back 后剩 2。
解析:本题考查两端弹出。 先删首 再删尾 ,只剩 输出。两端各删一个的对称操作。
排除法:C 答 的人只删了尾端—— 是被 pop_front 删掉的首元素;D 答 的人只删了首端;A 答 13 的人以为弹出是「留下被删端」。
01list<int> L; 02for (int x : {1, 2, 3, 4, 5}) L.push_back(x); 03// 依次:弹出首端输出、弹出末端输出、再弹首端输出、再弹末端输出
四个输出的数字与剩余 size() 是( )。
考点:正逆混合弹出(M3)。
(M3)考点:正逆混合弹出——1 5 2 4,剩 size 1。
解析:本题考查正逆混合弹出。:弹首得 、弹尾得 、再弹首得 、再弹尾得 ,只剩中位 、size 为 。交替吃两端是双端队列思想的雏形(deque 提高级)。
排除法:A 答 的人首尾次序对调;B 答剩 size 的人多数了剩余元素;C 答 的人只弹了首端。
01list<int> L; 02for (int x : {4, 1, 3}) L.push_back(x); 03int s = 0; 04for (int x : L) s += x; 05cout << s;
输出是( )。
考点:range-for 求和(M4)。
(M4)考点:range-for 求和——4+1+3=8。
解析:本题考查 range-for 求和。for (int x : L) 逐元素累加 。list 无下标,range-for 是它最自然的遍历形态(G6)。
排除法:A 答 的人把数字拼接当求和;B 答 的人某元素没加进;D 答 的人只累加了末元素。
01list<int> L; 02L.push_back(5); L.push_front(3); L.push_back(8); L.push_front(1); 03for (int x : L) cout << x;
输出是( )。
考点:双端操作序列(M5)。
(M5)考点:双端操作序列——back5、front3、back8、front1 得 1358。
解析:本题考查双端操作序列。尾 、头 、尾 、头 依次插入:,输出 1358。混合双端插入的逐态追踪。
排除法:D 答 5831 的人头尾操作对调;B 答 1385 的人尾插的两个位置错;C 答 3581 的人漏了最后的头插。
补全向 vector 尾部添加元素的语句:
01vector<int> v; 02for (int i = 1; i <= n; i++) 03 v./* 1 */(i);
空位 /* 1 */ 处应填( )。
考点:补 push_back(N1)。
(N1)考点:补 push_back——尾部追加的标准接口名。
解析:本题考查补 push_back。循环读入 个数依次 v.push_back(i) 收集成表。add、append、insert_back 都不是 STL 的名字——C++ 的接口命名自成体系。
排除法:A 填 add 的人带来了别的语言的习惯;C 填 append 的人同上;D 填 insert_back 的人接口名自造。
补全对 int a[N] 前 个元素的排序调用:
sort(a, /* 1 */);
空位 /* 1 */ 处应填( )。
考点:补 sort 区间(N2)。
(N2)考点:补 sort 区间——第二个参数是 a + n。
解析:本题考查补 sort 区间。左闭右开:首参 a 到尾参 a + n 覆盖前 个。填 a + n - 1 会漏掉最后一个元素(P4 的错误源)。
排除法:B 填 a + n - 1 的人把右开记成了右闭且少一位;C 填 n 的人给的是整数不是迭代位置;A 填 a[n] 的人既越界又类型不合。
补全「取出栈顶处理并弹出」的两步:
01int x = st./* 1 */; 02st.pop();
空位 /* 1 */ 处应填( )。
考点:补 stack 取顶(N3)。
(N3)考点:补 stack 取顶——先 top() 再 pop()。
解析:本题考查补 stack 取顶。取值用 top():看一眼、拿走值、再 pop 删除——两步各司其职。填 pop 的人拿不到值还把元素删了;front/back 是 queue/vector 的接口。
排除法:C 填 pop() 的人把只删不返的约定忘了;B 填 back() 的人错安了 queue/vector 接口;D 填 front() 的人同错。
补全「处理队头并出队」:
01int x = q./* 1 */; 02q.pop();
空位 /* 1 */ 处应填( )。
考点:补 queue 取队头(N4)。
(N4)考点:补 queue 取队头——先 front() 再 pop()。
解析:本题考查补 queue 取队头。与 N3 镜像:queue 的取值接口是 front()。top 是 stack 的、back 看的是队尾——三个取值接口在两容器间要分清。
排除法:C 填 top() 的人把栈的接口错安给队列;B 填 back() 的人取到了队尾;A 填 pop() 的人值没拿到队头先没了。
补全「处理完队头再出队」的语句顺序(处理为累加到 sum):
01while (!q.empty()) { 02 sum += q.front(); 03 /* 1 */; 04}
空位 /* 1 */ 处应填( )。
考点:补弹出时机(N5)。
(N5)考点:补弹出时机——处理完队头再 q.pop()。
解析:本题考查补弹出时机。循环体「sum 加 front、然后 pop」:先处理后删除顺序不能反——先 pop 就把要处理的元素删飞了。break 会让队列永远清不完。
排除法:A 填 q.push(sum) 的人把累加器塞进了队列;B 填 q.front() 的人重复取值没删元素——死循环;D 填 break 的人处理一个就跑。
01vector<int> v; 02for (int x : {5, 3, 8, 1}) v.push_back(x); 03sort(v.begin(), v.end()); 04for (int x : v) cout << x;
输出是( )。
考点:vector 加 sort(O1)。
(O1)考点:vector 加 sort——begin/end 整体排序得 1358。
解析:本题考查 vector 加 sort。收集 后 sort(v.begin(), v.end()) 升序输出 1358。vector 的区间参数用迭代器形式——与数组的 sort(a, a+n) 是同一语义的两种写法。
排除法:D 答 5381 的人没排序;B 答 8531 的人排成了降序;A 答 1835 的人排序结果错。
01stack<int> st; queue<int> q; 02for (int x : {1, 2, 3}) st.push(x); 03while (!st.empty()) { q.push(st.top()); st.pop(); } 04while (!q.empty()) { cout << q.front(); q.pop(); }
输出是( )。
考点:栈转队列(O2)。
(O2)考点:栈转队列——栈弹出序进队列得 321。
解析:本题考查栈转队列。 入栈后弹出的序是 ;逐个进队列再出队保持此序——输出 321。容器间「倒手」会改变或保持顺序,取决于中间容器的抽象。
排除法:D 答 123 的人忘了栈弹出已逆序;C 答 312 的人中途顺序错;A 答 213 的人某个环节对调。
01vector<int> v = {10, 20, 30}; 02stack<int> st; queue<int> q; 03for (int x : v) st.push(x); 04for (int x : v) q.push(x); 05cout << st.top() << " " << q.front() << " " << q.back();
输出是( )。
考点:三容器同装(O3)。
(O3)考点:三容器同装——{10,20,30} 的栈顶 30、队头 10、队尾 30。
解析:本题考查三容器同装。同批数据进不同容器视角不同:stack 的 top 是末元素 ;queue 的 front 是首元素 、back 是末元素 。同一数据的「容器视角」对照是理解接口差异的最好练习。
排除法:A 答 10 30 10 的人把 stack 与 queue 的视角对调;C 答 30 30 10 的人 queue 两端取反;D 答 10 10 30 的人 stack 的 top 取错。
01struct P { string name; int sc; }; 02vector<P> v = {{"Li", 85}, {"Zhao", 92}, {"Wang", 78}}; 03sort(v.begin(), v.end(), [](const P& a, const P& b) { return a.sc > b.sc; }); 04cout << v[0].name;
输出是( )。
考点:结构体 vector 排序(O4)。
(O4)考点:结构体 vector 排序——按分数降序首名 Zhao。
解析:本题考查结构体 vector 排序。vector<P> 配比较器 a.sc > b.sc 按分数降序: 分的 Zhao 居首。结构体 + vector + sort 三件套是竞赛数据处理的标准组合(08 卷深入)。
排除法:B 答 Li 的人用了升序;D 答 Wang 的人同样方向错;C 选编译错误的人低估了模板与比较器的配合能力。
vector<int> v; v.push_back(1); 之后执行 cout << v[5];,结果是( )。
考点:vector 越界下标(P1)。
(P1)考点:vector 越界下标——v[5] 无检查读垃圾或崩溃。
解析:本题考查 vector 越界下标。只有 个元素的 vector 被 v[5] 访问:operator[] 不做边界检查,读到越界内存的垃圾值或直接崩溃——结果未定义。要带检查用 v.at(5)(会抛异常)。
排除法:B 答输出 的人以为越界默认零;C 答编译错误的人高估了运行期访问的检查;D 答自动扩容的人把 push_back 的行为错安给了下标。
stack<int> st; 空栈直接执行 st.top(),结果是( )。
考点:空栈 top 崩溃(P2)。
(P2)考点:空栈 top 崩溃——未定义行为,先判空。
解析:本题考查空栈 top 崩溃。空栈没有栈顶,top() 行为未定义——典型表现是程序崩溃。所有 top/pop 前配 empty() 判断(E4)是铁律。
排除法:B 答返回 的人以为有空默认值;A 答返回 的人虚构了哨兵返回;C 答编译错误的人把运行期行为当成了编译期检查。
int x = st.pop(); 这行代码( )。
考点:pop 返回值误解(P3)。
(P3)考点:pop 返回值误解——int x = st.pop() 编译不过。
解析:本题考查 pop 返回值误解。pop() 返回 void,赋值给 int 直接编译错误——不是运行错误。正确写法 x = st.top(); st.pop(); 两步走。stack、queue、vector 的 pop 系列全都是这一约定。
排除法:D 答正常存进 x 的人给 void 虚构了返回值;C 答运行时崩溃的人把编译期类型错误错报成运行期;B 答弹出两个元素的人想象了额外行为。
要排序 a[0..n-1] 共 个元素却写成 sort(a, a + n - 1);,后果是( )。
考点:sort 区间少一位(P4)。
(P4)考点:sort 区间少一位——a+n-1 漏掉末元素。
解析:本题考查 sort 区间少一位。要排 个却传 a + n - 1(右开语义只覆盖到下标 ):最后一个元素不参与排序,输出可能整体不升序。左闭右开的「尾后一格」要记牢(A7)。
排除法:A 答第一个元素不参与的人把缺口方向弄反;C 答全部正常的人没发现少排一个;D 答编译错误的人把逻辑错误错报成语法错误。
for (int i = 0; i < (int)v.size(); i++) 循环体内执行了 v.pop_back();,可能的后果是( )。
考点:遍历中修改容器(P5)。
(P5)考点:遍历中修改容器——size 收缩致遍历提前结束。
解析:本题考查遍历中修改容器。循环条件每轮都重新取 v.size():体内 pop_back 让 size 变小,原计划的遍历次数提前到站。「边遍历边增删」要么按固定次数缓存、要么明确这是本意——盲写必错。
排除法:A 答一定死循环的人方向反了——收缩只会提前结束;C 答没有影响的人没意识到条件每轮重估;B 答编译错误的人把运行逻辑当成了语法限制。