单调队列的定义是?
考点:单调队列的定义(A1)。
解析:队列内元素单调——插入时从队尾弹出破坏单调性的元素。✅ 正确
排除法:无(判断题)。混淆点:比普通 FIFO 多"尾维护"。
关联 · 与普通队列的区别(A3):增量动作。
单调队列主要解决?
考点:单调队列解决的问题(A2)。
解析:滑动窗口最值—— 求所有窗口的最大/最小值。✅ 正确
排除法:无(判断题)。混淆点:排序/字符串/最短路不是单调队列主场。
关联 · 滑动窗口(C 组):主场问题。
判断题:普通队列只在队尾插入;单调队列插入时还从队尾弹出破坏单调性的元素——多一个"尾维护"动作。
考点:与普通队列的区别(A3)。
解析:普通队列只尾插;单调队列插入时还从队尾弹破坏单调的元素。✅ 正确
排除法:无(判断题)。混淆点:尾维护是单调性的来源。
关联 · 队尾维护单调性(B1):尾维护细节。
判断题:优先队列每次取全局最值;单调队列取"窗口内"最值且还保序——两者用途不同。
考点:与优先队列的区别(A4)。
解析:优先队列取全局最值;单调队列取窗口内最值且保序。✅ 正确
排除法:无(判断题)。混淆点:窗口语义是单调队列的独门。
关联 · 优先队列回顾(F1):对比对象。
单调队列的典型应用是?
考点:应用场景(A5)。
解析:滑动窗口最值、单调队列优化 DP。✅ 正确
排除法:无(判断题)。混淆点:DP 优化是进阶应用(转移式含滑动最值)。
关联 · 应用总表(G5):用途清单。
单调队列处理滑动窗口的复杂度是?
考点:复杂度(A6)。
解析:——每个元素入队出队各一次。✅ 正确
排除法:无(判断题)。混淆点:均摊分析——虽然 while 弹多次,总计仍 。
关联 · 复杂度总表(G3):总表。
维护递减队列(求窗口最大),插入新元素时队尾操作是?
考点:队尾维护单调性(B1)。
解析:递减队列(求最大):while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 再 push。✅ 正确
排除法:无(判断题)。混淆点:<=(等于也弹)保持严格递减。
关联 · 队尾维护输出(I1):代码版。
判断题:窗口右移后,队头下标若超出窗口左边界则弹出——过期元素必须清除。
考点:队头过期元素弹出(B2)。
解析:队头下标超出窗口左边界则弹出——过期必清。✅ 正确
排除法:无(判断题)。混淆点:忘弹过期 = 经典错误(H1/P1)。
关联 · 忘弹过期元素(P1):错误示范。
单调队列存下标而非值,原因是?
考点:存下标的原因(B3)。
解析:判断过期(下标 < 窗口左边界)必须知道下标。✅ 正确
排除法:无(判断题)。混淆点:存值无法判断窗口位置。
关联 · 下标存储输出(I4):代码版。
滑动窗口求最大值的完整流程是?
考点:滑动窗口流程(B4)。
解析:四步 = 弹过期 → 尾维护 → 插入 → 输出队头。✅ 正确
排除法:无(判断题)。混淆点:顺序不能乱(先弹过期再维护)。
关联 · 滑动窗口代码框架(C5):框架。
判断题:单调队列常用 deque 实现——需要队头弹(pop_front)与队尾弹(pop_back)两个方向。
考点:deque 实现(B5)。
解析:单调队列用 deque——需要 pop_front 与 pop_back 两方向。✅ 正确
排除法:无(判断题)。混淆点:普通 queue 只有一端。
关联 · deque(E 组):底层容器。
判断题:单调队列也可用数组 + 头尾指针模拟(q[head..tail])——与循环队列类似的技巧。
考点:数组模拟实现(B6)。
解析:数组 + 头尾指针(q[head..tail])同样可模拟。✅ 正确
排除法:无(判断题)。混淆点:与循环队列同技巧。
关联 · deque 实现(B5):两种写法。
判断题:单调队列实现三要素 = 尾维护单调、头弹过期、存下标——缺一不可。
考点:实现综合(B7)。
解析:三要素 = 尾维护、头弹过期、存下标——缺一不可。✅ 正确
排除法:无(判断题)。混淆点:三要素是本卷实现细节的核心。
关联 · 实现综合(B7 与 I 组):代码组。
滑动窗口问题的描述是?
考点:滑动窗口问题(C1)。
解析:长 窗口滑动、求每个位置窗口最值。✅ 正确
排除法:无(判断题)。混淆点:不是只求一个最值。
关联 · 单调队列解决的问题(A2):问题定义。
数组 {1, 3, -1, -3, 5, 3, 6, 7}、窗口 的最大值序列是?
考点:窗口最大值(C2)。
解析:、k=3 最大序列 3 3 5 5 6 7。✅ 正确
排除法:无(判断题)。混淆点:手算验证——第一个窗口 {1,3,-1} 最大 3。
关联 · 滑动窗口最大值(I2):代码版。
同数组窗口 的最小值序列是?
考点:窗口最小值(C3)。
解析:同数组最小序列 -1 -3 -3 -3 3 3。✅ 正确
排除法:无(判断题)。混淆点:递增队列求最小。
关联 · 滑动窗口最小值(I3):代码版。
判断题:滑动窗口暴力每个窗口扫一遍是 ;单调队列 —— 大时差距巨大。
考点:暴力对比(C4)。
解析:暴力 vs 单调队列 。✅ 正确
排除法:无(判断题)。混淆点: 大时差距数量级。
关联 · 暴力操作量(J6):代码版。
判断题:滑动窗口框架 = 循环 i 从 1 到 n:弹过期 → 尾维护 → 插入 → i ≥ k 时输出队头。
考点:代码框架(C5)。
解析:循环四步——弹过期、尾维护、插入、i≥k 输出。✅ 正确
排除法:无(判断题)。混淆点:输出条件 i >= k(窗口完整)。
关联 · 滑动窗口流程(B4):框架化。
判断题:滑动窗口变体 = 窗口和(前缀和即可)、窗口最值(单调队列)、窗口计数——按需选工具。
考点:滑动窗口变体(C6)。
解析:窗口和(前缀和)、窗口最值(单调队列)、窗口计数——按需选工具。✅ 正确
排除法:无(判断题)。混淆点:和不需要单调队列。
关联 · 选择矩阵(G2):选型。
判断题:滑动窗口最值是单调队列的"主场问题"—— 且实现极短。
考点:综合(C7)。
解析:滑动窗口最值是单调队列的主场—— 且极短。✅ 正确
排除法:无(判断题)。混淆点:模板约 10 行。
关联 · 滑动窗口代码(J 组):代码组。
单调栈的定义是?
考点:单调栈的定义(D1)。
解析:栈内单调——插入时弹出破坏单调的栈顶。✅ 正确
排除法:无(判断题)。混淆点:与单调队列同思想、容器不同。
关联 · 与单调队列对比(D6):容器差异。
单调栈主要解决?
考点:单调栈解决的问题(D2)。
解析:下一个更大/更小元素、柱状图最大矩形。✅ 正确
排除法:无(判断题)。混淆点:排序/最短路/字符串不用单调栈。
关联 · 下一个更大元素(K2):代码版。
求"下一个更大元素"用递减栈——插入新元素时栈顶操作是?
考点:递减栈流程(D3)。
解析:求下一个更大用递减栈——栈顶比当前小则弹并记录答案。✅ 正确
排除法:无(判断题)。混淆点:方向是高频易错(H2/P2)。
关联 · 递减栈过程(K1):代码版。
求"下一个更小元素"用递增栈——判定条件是?
考点:递增栈流程(D4)。
解析:下一个更小用递增栈——a[st.top()] > a[i] 时弹。✅ 正确
排除法:无(判断题)。混淆点:与递减栈对称。
关联 · 下一个更小元素(K3):代码版。
柱状图最大矩形问题的单调栈思路是?
考点:柱状图最大矩形(D5)。
解析:每根柱子找左右第一个更矮的确定宽度——递增栈维护。✅ 正确
排除法:无(判断题)。混淆点:宽度 = 左右更矮柱之间的跨度。
关联 · 柱状图最大矩形(K6):代码版。
判断题:单调栈与单调队列同是"弹出破坏单调的元素"——差别在容器(栈一端 vs 队列两端+过期)。
考点:与单调队列对比(D6)。
解析:同是"弹破坏单调的元素"——栈一端、队列两端+过期。✅ 正确
排除法:无(判断题)。混淆点:队列的"过期"是栈没有的概念。
关联 · 单调队列(A 组):对比参照。
判断题:单调栈 解决"每个元素两侧最近的最值"类问题——是单调队列的"栈版"。
考点:综合(D7)。
解析:单调栈 解决"两侧最近最值"类问题。✅ 正确
排除法:无(判断题)。混淆点:"两侧"与队列的"窗口"互补。
关联 · 单调栈代码(K 组):代码组。
deque(双端队列)是?
考点:deque 的定义(E1)。
解析:双端队列——两端都能插入删除。✅ 正确
排除法:无(判断题)。混淆点:栈/队列是其受限特例。
关联 · deque 的四种操作(E2):操作集。
deque 的四端操作是?
考点:deque 的四种操作(E2)。
解析:push_front/push_back/pop_front/pop_back。✅ 正确
排除法:无(判断题)。混淆点:四操作全 。
关联 · deque 基本操作(L1):代码版。
判断题:deque 同时具备栈(一端)与队列(另一端)的能力——是两者的超集。
考点:与 queue 和 stack 对比(E3)。
解析:deque 是栈与队列的超集。✅ 正确
排除法:无(判断题)。混淆点:一端当栈、另一端当队列。
关联 · deque 当栈(N3):代码版。
deque 的典型应用是?
考点:deque 的应用(E4)。
解析:单调队列底层、0-1 BFS。✅ 正确
排除法:无(判断题)。混淆点:双端 BFS 是 deque 的进阶应用。
关联 · 0-1 BFS 思想(E5):应用展开。
判断题:0-1 BFS(边权只有 0 和 1 的最短路)用 deque——0 权边插队头、1 权边插队尾。
考点:0-1 BFS 思想(E5)。
解析:边权 0/1 的最短路——0 权插队头、1 权插队尾。✅ 正确
排除法:无(判断题)。混淆点:0 权优先 = 保持队列有序。
关联 · deque 应用(L5):代码版。
判断题:deque 的定位 = "需要两端操作"的场景——单调队列、双端 BFS、滑动窗口。
考点:综合(E6)。
解析:deque 定位 = 两端操作的场景。✅ 正确
排除法:无(判断题)。混淆点:单端场景用 stack/queue 即可。
关联 · deque 代码(L 组):代码组。
判断题:priority_queue 默认大根堆(队首最大)、greater 变小根堆——插入删除 、取顶 。
考点:优先队列回顾(F1)。
解析:priority_queue 默认大根堆、greater 小根堆——插删 、取顶 。✅ 正确
排除法:无(判断题)。混淆点:与 20 章堆衔接。
关联 · 优先队列填空(O5):填空版。
延迟删除(lazy deletion)思想是?
考点:延迟删除(F2)。
解析:失效元素不立即删,浮到堆顶再弹——避免 查找删除。✅ 正确
排除法:无(判断题)。混淆点:取顶前判失效是配套纪律(H4)。
关联 · 延迟删除输出(M1):代码版。
判断题:对顶堆 = 大根堆存小半 + 小根堆存大半——动态维护中位数 。
考点:对顶堆回顾(F3)。
解析:大根堆小半 + 小根堆大半——动态中位数 。✅ 正确
排除法:无(判断题)。混淆点:平衡条件是两堆大小差 ≤ 1。
关联 · 对顶堆输出(M2):代码版。
判断题:优先队列是贪心算法的标配——"每次取当前最优"的动态场景(合并果子/任务调度/多路归并)。
考点:优先队列加贪心(F4)。
解析:贪心"每次取当前最优"的动态场景 = 优先队列标配。✅ 正确
排除法:无(判断题)。混淆点:合并果子/任务调度/多路归并皆如此。
关联 · 贪心加优先队列(M3):代码版。
判断题:优先队列应用总表——top-k、对顶堆中位数、合并果子、Dijkstra、任务调度、多路归并。
考点:应用总表(F5)。
解析:top-k、对顶堆、合并果子、Dijkstra、任务调度、多路归并。✅ 正确
排除法:无(判断题)。混淆点:Dijkstra 是优先队列的图论应用(30 章之后衔接)。
关联 · 应用总表(G5):汇总。
判断题:优先队列的价值 = 动态维护"当前最优"——与单调队列的"窗口最值"互补。
考点:综合(F6)。
解析:优先队列 = 动态"当前最优";单调队列 = "窗口最值"——互补。✅ 正确
排除法:无(判断题)。混淆点:两结构的语义区分。
关联 · 四结构总表(G1):总表。
单调队列、单调栈、deque、优先队列的总表是?
考点:四结构总表(G1)。
解析:单调队列窗口最值 、单调栈下一个更大 、deque 两端 、优先队列动态最值 。✅ 正确
排除法:无(判断题)。混淆点:数据结构板块收官总表。
关联 · 复杂度总表(G3):数字版。
滑动窗口最大值,选?
考点:选择矩阵(G2)。
解析:滑动窗口最大 → 单调队列( 优于优先队列 )。✅ 正确
排除法:无(判断题)。混淆点:优先队列可行但非最优。
关联 · 选择综合(G6):选型练习。
判断题:复杂度总表——单调队列/栈 、deque 操作 、优先队列 单次。
考点:复杂度总表(G3)。
解析:单调队列/栈 、deque 操作 、优先队列 。✅ 正确
排除法:无(判断题)。混淆点:单调结构的 是均摊。
关联 · 复杂度(A6):单调队列复杂度。
判断题:单调结构(队列/栈)是"线性扫描 + 维护单调";优先队列是"动态最值"——两类互补。
考点:综合对比(G4)。
解析:单调结构(线性扫描+维护单调)vs 优先队列(动态最值)——互补。✅ 正确
排除法:无(判断题)。混淆点:两类问题模式。
关联 · 四结构总表(G1):分类。
判断题:应用总表——窗口最值/下一个更大/双端 BFS/top-k/中位数/Dijkstra——四结构各有主场。
考点:应用总表(G5)。
解析:窗口最值/下一个更大/双端 BFS/top-k/中位数/Dijkstra——各有主场。✅ 正确
排除法:无(判断题)。混淆点:六大应用的选型总表。
关联 · 选择矩阵(G2):选型依据。
需要"每个位置的左侧最近更大元素",选?
考点:选择综合(G6)。
解析:左侧最近更大 → 单调栈。✅ 正确
排除法:无(判断题)。混淆点:"左侧/右侧最近"是单调栈的信号词。
关联 · 单调栈解决的问题(D2):信号词识别。
判断题:单调队列忘弹过期队头,窗口外的旧最值会"污染"结果——过期判断是必须的。
考点:单调队列忘弹过期(H1)。
解析:忘弹过期 → 窗口外旧最值污染结果。✅ 正确
排除法:无(判断题)。混淆点:P1 递减数组实测输出 9 9 9 而非 9 8 7。
关联 · 忘弹过期元素(P1):错误示范。
判断题:求下一个更大用递减栈(栈顶比当前小才弹)——方向写反(递增栈)会得到错误答案。
考点:单调栈方向错(H2)。
解析:下一个更大用递减栈——方向反(递增)得错误答案。✅ 正确
排除法:无(判断题)。混淆点:P2 实测方向反输出 1 0 3 0 而非 5 5 0 0。
关联 · 单调栈方向反(P2):错误示范。
判断题:deque 为空时访问 front()/back() 是未定义行为——访问前必须判空。
考点:deque 空时访问(H3)。
解析:空 deque 访问 front()/back() 是未定义行为——必判空。✅ 正确
排除法:无(判断题)。混淆点:pop 空也是未定义。
关联 · deque 越界(P3):错误示范。
判断题:延迟删除时每次取顶都要检查"是否已失效"——忘判会把失效元素当真值用。
考点:延迟删除忘判(H4)。
解析:延迟删除取顶前必须判失效——忘判把失效值当真。✅ 正确
排除法:无(判断题)。混淆点:P4 实测漏判输出 5 而非 3。
关联 · 延迟删除漏判(P4):错误示范。
判断题:以下结论全部正确——"单调队列尾维护+头弹过期+存下标;单调栈递减求下一个更大;deque 空访问非法;延迟删除取顶前判失效"。
考点:综合判断(H5)。
解析:五结论全对——尾维护+头弹过期+存下标、递减栈求更大、deque 判空、延迟删除判失效。✅ 正确
排除法:无(判断题)。混淆点:数据结构板块收官章的核心自查。
关联 · 本章全部核心结论:收官综合判断题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[6] = {0, 5, 3, 4, 2, 1}; // 下标 1 起 05 deque<int> q; // 存下标,维护递减 06 for (int i = 1; i <= 5; i++) { 07 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 08 q.push_back(i); 09 } 10 for (int x : q) cout << a[x] << " "; 11 return 0; 12}
单选题:程序输出是?(最终递减队列中的元素值)
考点:队尾维护输出(I1)。
解析:递减队列最终存 {5,4,2,1}——3 被 4 顶掉、其他保持递减。正确答案 A。
实现要点:a[q.back()] <= a[i] 时 pop_back 再 push。手算:逐个插入模拟。
排除法:B 是原序;C 是升序;D 无依据。
关联 · 队尾维护单调性(B1):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[9] = {0, 1, 3, -1, -3, 5, 3, 6, 7}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 8; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); // 弹过期 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); // 尾维护 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 k=3 的最大值序列)
考点:滑动窗口最大值(I2)。
解析:k=3 最大序列 3 3 5 5 6 7。正确答案 A。
实现要点:四步循环 = 弹过期、尾维护、插入、输出。手算:逐窗口验证。
排除法:B 漏窗口;C 是倒序;D 无依据。
关联 · 滑动窗口(C1):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[9] = {0, 1, 3, -1, -3, 5, 3, 6, 7}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 8; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] >= a[i]) q.pop_back(); // 递增队列 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 k=3 的最小值序列)
考点:滑动窗口最小值(I3)。
解析:递增队列求最小 → -1 -3 -3 -3 3 3。正确答案 A。
实现要点:>= 弹更大的(递增)。手算:逐窗口。
排除法:B 漏首个窗口;C/D 无依据。
关联 · 窗口最小值(C3):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[6] = {0, 9, 8, 7, 6, 5}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 5; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(递减序列的窗口最大值——每个窗口都是递减的,答案恒为窗口左端)
考点:下标存储输出(I4)。
解析:递减数组窗口最大 = 窗口左端 → 9 8 7。正确答案 A。
实现要点:队头是最大值的下标。手算:窗口左移一位。
排除法:B 是恒 9(忘弹过期的 P1 情形);C/D 无依据。
关联 · 存下标的原因(B3):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[9] = {0, 1, 3, -1, -3, 5, 3, 6, 7}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 8; i++) { 08 while (!q.empty() && ______) q.pop_front(); // 弹过期 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:横线处应填入?(使输出为 3 3 5 5 6 7)
考点:单调队列填空(I5)。
解析:弹过期条件 q.front() < i - k + 1。正确答案 A。
实现要点:窗口左边界 = i - k + 1。手算:i=4、k=3 时边界 2。
排除法:B 漏 +1;C/D 无依据。
关联 · 队头过期元素弹出(B2):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[7] = {0, 2, 1, 4, 3, 6, 5}; 05 int k = 4; 06 deque<int> q; 07 for (int i = 1; i <= 6; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 k=4 的最大值序列:窗口 [1,4]=4、[2,5]=6、[3,6]=6)
考点:综合(I6)。
解析:k=4 窗口最大 4 6 6。正确答案 A。
实现要点:完整四步循环。手算:[1,4]={2,1,4,3}、[2,5]={1,4,3,6}、[3,6]={4,3,6,5}。
排除法:B/C/D 无依据。
关联 · 滑动窗口最大值(I2):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[8] = {0, 4, 2, 6, 1, 8, 3, 5}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 7; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 [1,3]=6、[2,4]=6、[3,5]=8、[4,6]=8、[5,7]=8)
考点:窗口最大值序列(J1)。
解析:6 6 8 8 8。正确答案 A。
实现要点:逐窗口手算。手算:[1,3]=6、[2,4]=6、[3,5]=8、[4,6]=8、[5,7]=8。
排除法:B/C/D 无依据。
关联 · 滑动窗口最大值(I2):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[8] = {0, 4, 2, 6, 1, 8, 3, 5}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 7; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] >= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 [1,3]=2、[2,4]=1、[3,5]=1、[4,6]=1、[5,7]=3)
考点:窗口最小值序列(J2)。
解析:2 1 1 1 3。正确答案 A。
实现要点:递增队列。手算:[1,3]=2、[2,4]=1、[3,5]=1、[4,6]=1、[5,7]=3。
排除法:B/C/D 无依据。
关联 · 滑动窗口最小值(I3):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[6] = {0, 3, 1, 4, 1, 5}; 05 int k = 2; 06 deque<int> q; 07 for (int i = 1; i <= 5; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 k=2:{3,1}→3、{1,4}→4、{4,1}→4、{1,5}→5)
考点:窗口大小变化(J3)。
解析:k=2 最大序列 3 4 4 5。正确答案 A。
实现要点:窗口小时过期更频繁。手算:{3,1}→3、{1,4}→4、{4,1}→4、{1,5}→5。
排除法:B/C/D 无依据。
关联 · 滑动窗口变体(C6):参数变化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[9] = {0, 1, 3, -1, -3, 5, 3, 6, 7}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 8; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] >= a[i]) ______; // 求最小值:弹更大的 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:横线处应填入?(使输出为 -1 -3 -3 -3 3 3)
考点:滑动窗口填空(J4)。
解析:求最小弹更大 → q.pop_back()。正确答案 A。
实现要点:递增维护的弹出动作。手算:验证最小序列。
排除法:B 弹队头(错方向);C/D 无依据。
关联 · 队尾维护单调性(B1):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[9] = {0, 8, 3, 5, 2, 7, 1, 9, 4}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 8; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 [1,3]=8、[2,4]=5、[3,5]=7、[4,6]=7、[5,7]=9、[6,8]=9)
考点:窗口综合(J5)。
解析:8 5 7 7 9 9。正确答案 A。
实现要点:完整四步循环。手算:[1,3]=8、[2,4]=5、[3,5]=7、[4,6]=7、[5,7]=9、[6,8]=9。
排除法:B/C/D 无依据。
关联 · 滑动窗口最大值(I2):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 长为 n 的数组、窗口 k,暴力 O(nk) vs 单调队列 O(n) 05 int n = 1000000, k = 1000; 06 cout << (long long)n * k; // 暴力操作量 07 return 0; 08}
单选题:程序输出是?(暴力 10^9 vs 单调队列 10^6 的差距)
考点:窗口应用(J6)。
解析:暴力操作量 。正确答案 A。
实现要点:暴力与单调队列的差距。手算:乘法。
排除法:B 是单调队列;C/D 无依据。
关联 · 暴力对比(C4):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[5] = {0, 2, 5, 3, 4}; // 下标 1 起 05 stack<int> st; 06 for (int i = 1; i <= 4; i++) { 07 while (!st.empty() && a[st.top()] < a[i]) st.pop(); // 递减栈 08 st.push(i); 09 } 10 vector<int> out; 11 while (!st.empty()) { out.push_back(a[st.top()]); st.pop(); } 12 for (int i = out.size() - 1; i >= 0; i--) cout << out[i] << " "; 13 return 0; 14}
单选题:程序输出是?(从底到顶的递减栈内容)
考点:递减栈过程(K1)。
解析:递减栈最终 {5,4}(2、3 被顶掉)。正确答案 A。
实现要点:栈顶比当前小则弹。手算:2 入、5 弹 2、3 入、4 弹 3。
排除法:B 是原序;C 是升序;D 无依据。
关联 · 递减栈流程(D3):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[5] = {0, 2, 1, 5, 3}; // 下标 1 起 05 int ans[5] = {0}; 06 stack<int> st; 07 for (int i = 1; i <= 4; i++) { 08 while (!st.empty() && a[st.top()] < a[i]) { 09 ans[st.top()] = a[i]; // 栈顶的下一个更大 = a[i] 10 st.pop(); 11 } 12 st.push(i); 13 } 14 for (int i = 1; i <= 4; i++) cout << ans[i] << " "; 15 return 0; 16}
单选题:程序输出是?(各元素的下一个更大元素,无则为 0:2→5、1→5、5→0、3→0)
考点:下一个更大元素(K2)。
解析:2→5、1→5、5→0、3→0 → 5 5 0 0。正确答案 A。
实现要点:递减栈,弹栈顶时记录答案。手算:逐个处理。
排除法:B/C/D 无依据。
关联 · 单调栈解决的问题(D2):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[5] = {0, 4, 2, 5, 1}; // 下标 1 起 05 int ans[5] = {0}; 06 stack<int> st; 07 for (int i = 1; i <= 4; i++) { 08 while (!st.empty() && a[st.top()] > a[i]) { // 递增栈:栈顶更大则弹 09 ans[st.top()] = a[i]; 10 st.pop(); 11 } 12 st.push(i); 13 } 14 for (int i = 1; i <= 4; i++) cout << ans[i] << " "; 15 return 0; 16}
单选题:程序输出是?(各元素的下一个更小元素:4→2、2→1、5→1、1→0)
考点:下一个更小元素(K3)。
解析:4→2、2→1、5→1、1→0 → 2 1 1 0。正确答案 A。
实现要点:递增栈。手算:逐个处理。
排除法:B/C/D 无依据。
关联 · 递增栈流程(D4):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[5] = {0, 2, 1, 5, 3}; 05 int ans[5] = {0}; 06 stack<int> st; 07 for (int i = 1; i <= 4; i++) { 08 while (!st.empty() && ______) { // 下一个更大:栈顶更小则弹 09 ans[st.top()] = a[i]; 10 st.pop(); 11 } 12 st.push(i); 13 } 14 for (int i = 1; i <= 4; i++) cout << ans[i] << " "; 15 return 0; 16}
单选题:横线处应填入?(使输出为 5 5 0 0)
考点:单调栈填空(K4)。
解析:a[st.top()] < a[i]——下一个更大的弹出条件。正确答案 A。
实现要点:递减栈方向。手算:验证 5 5 0 0。
排除法:B 方向反;C/D 无依据。
关联 · 递减栈流程(D3):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[6] = {0, 6, 4, 8, 2, 5}; // 下标 1 起 05 stack<int> st; 06 for (int i = 1; i <= 5; i++) { 07 while (!st.empty() && a[st.top()] < a[i]) st.pop(); 08 st.push(i); 09 } 10 cout << st.size(); 11 return 0; 12}
单选题:程序输出是?(处理完后的递减栈大小)
考点:栈内元素输出(K5)。
解析:递减栈最终大小 2({8,5})。正确答案 A。
实现要点:数栈中元素。手算:6 入、4 入、8 弹 4 弹 6、2 入、5 弹 2。
排除法:B/C/D 无依据。
关联 · 递减栈过程(K1):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 柱状图最大矩形:heights = {2,1,5,6,2,3},最大面积 10 05 int h[7] = {0, 2, 1, 5, 6, 2, 3}; 06 int n = 6, mx = 0; 07 for (int i = 1; i <= n; i++) { 08 int l = i, r = i; 09 while (l > 1 && h[l - 1] >= h[i]) l--; // 暴力左右扩展(单调栈加速版同理) 10 while (r < n && h[r + 1] >= h[i]) r++; 11 mx = max(mx, h[i] * (r - l + 1)); 12 } 13 cout << mx; 14 return 0; 15}
单选题:程序输出是?(最大矩形面积)
考点:单调栈应用(K6)。
解析:柱状图最大矩形 = 10(高度 5 宽 2 的 5×2)。正确答案 A。
实现要点:左右扩展找更矮柱。手算:h=5 左右到 1 → 宽 2。
排除法:B/C/D 无依据。
关联 · 柱状图最大矩形(D5):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[5] = {0, 3, 1, 2, 4}; // 下标 1 起 05 int ans[5] = {0}; 06 stack<int> st; 07 for (int i = 1; i <= 4; i++) { 08 while (!st.empty() && a[st.top()] < a[i]) { 09 ans[st.top()] = a[i]; 10 st.pop(); 11 } 12 st.push(i); 13 } 14 for (int i = 1; i <= 4; i++) cout << ans[i] << " "; 15 return 0; 16}
单选题:程序输出是?(3→4、1→2、2→4、4→0)
考点:综合(K7)。
解析:3→4、1→2、2→4、4→0 → 4 2 4 0。正确答案 A。
实现要点:递减栈全流程。手算:逐个处理。
排除法:B/C/D 无依据。
关联 · 下一个更大元素(K2):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 deque<int> q; 05 q.push_back(1); q.push_back(2); q.push_front(3); 06 cout << q.front() << " " << q.back() << " " << q.size(); 07 return 0; 08}
单选题:程序输出是?
考点:deque 基本操作(L1)。
解析:push_back(1)、push_back(2)、push_front(3) → front 3、back 2、size 3。正确答案 A。
实现要点:四操作语义。手算:画队列。
排除法:B/C/D 无依据。
关联 · deque 的四种操作(E2):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 deque<int> q; 05 q.push_back(1); q.push_back(2); q.push_back(3); 06 q.pop_front(); // 弹 1 07 q.pop_back(); // 弹 3 08 cout << q.front() << " " << q.back(); 09 return 0; 10}
单选题:程序输出是?
考点:两端操作输出(L2)。
解析:弹头 1、弹尾 3 → 剩 2。正确答案 A。
实现要点:两端弹。手算:画队列。
排除法:B/C/D 无依据。
关联 · deque 基本操作(L1):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[6] = {0, 3, 1, 4, 1, 5}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 5; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 [1,3]=4、[2,4]=4、[3,5]=5)
考点:deque 模拟滑动窗口(L3)。
解析:k=3 最大 4 4 5。正确答案 A。
实现要点:deque 当单调队列容器。手算:{3,1,4}→4、{1,4,1}→4、{4,1,5}→5。
排除法:B/C/D 无依据。
关联 · deque 实现(B5):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 deque<int> q; 05 q.push_back(5); 06 ______; // 队头插入 1 07 cout << q.front(); 08 return 0; 09}
单选题:横线处应填入?(使输出为 1)
考点:deque 填空(L4)。
解析:q.push_front(1)。正确答案 A。
实现要点:队头插入。手算:front = 1。
排除法:B 尾插(front 仍 5);C/D 无依据。
关联 · deque 的四种操作(E2):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 0-1 BFS:0 权边插队头、1 权边插队尾 05 deque<int> q; 06 q.push_back(1); // 1 权边 07 q.push_front(0); // 0 权边 08 q.push_back(1); 09 for (int x : q) cout << x << " "; 10 return 0; 11}
单选题:程序输出是?
考点:deque 应用(L5)。
解析:0 权插头、1 权插尾 → 0 1 1。正确答案 A。
实现要点:0-1 BFS 的插入策略。手算:画队列。
排除法:B/C/D 无依据。
关联 · 0-1 BFS 思想(E5):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 deque<int> q; 05 for (int i = 1; i <= 5; i++) q.push_back(i); 06 q.pop_front(); q.pop_front(); // 剩 3 4 5 07 q.push_front(2); q.push_front(1); // 1 2 3 4 5 08 for (int x : q) cout << x << " "; 09 return 0; 10}
单选题:程序输出是?
考点:综合(L6)。
解析:弹两头、插两头 → 1 2 3 4 5。正确答案 A。
实现要点:四操作组合。手算:逐步模拟。
排除法:B/C/D 无依据。
关联 · deque 综合(E6):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 延迟删除:元素失效不打标记删除,等浮到堆顶再弹 05 priority_queue<int> q; 06 bool valid[10] = {0}; 07 q.push(5); valid[5] = true; 08 q.push(3); valid[3] = true; 09 valid[5] = false; // 5 失效(不立即删) 10 while (!q.empty() && !valid[q.top()]) q.pop(); // 取顶时清理 11 cout << q.top(); 12 return 0; 13}
单选题:程序输出是?(失效的 5 被延迟清理,取到有效的 3)
考点:延迟删除输出(M1)。
解析:5 失效浮到堆顶被清理 → 取到 3。正确答案 A。
实现要点:取顶前 while (!q.empty() && !valid[q.top()]) q.pop();。手算:5 失效 → 弹 → 3。
排除法:B 是漏判(P4);C/D 无依据。
关联 · 延迟删除(F2):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 对顶堆求中位数:{1,2,3,4,5} 的中位数 3 05 priority_queue<int> maxh; // 小半 06 priority_queue<int, vector<int>, greater<int>> minh; // 大半 07 int d[5] = {3, 1, 4, 2, 5}; 08 for (int i = 0; i < 5; i++) { 09 int x = d[i]; 10 if (maxh.empty() || x <= maxh.top()) maxh.push(x); 11 else minh.push(x); 12 if ((int)maxh.size() > (int)minh.size() + 1) { minh.push(maxh.top()); maxh.pop(); } 13 if ((int)minh.size() > (int)maxh.size()) { maxh.push(minh.top()); minh.pop(); } 14 } 15 cout << maxh.top(); 16 return 0; 17}
单选题:程序输出是?
考点:对顶堆输出(M2)。
解析:{3,1,4,2,5} 中位数 3。正确答案 A。
实现要点:大根堆小半 + 小根堆大半平衡。手算:排序 {1,2,3,4,5} 中位 3。
排除法:B/C/D 无依据。
关联 · 对顶堆回顾(F3):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 合并果子:{1,2,9} → 1+2=3(代价 3)→ 3+9=12 → 总 15 05 priority_queue<int, vector<int>, greater<int>> q; 06 int d[3] = {1, 2, 9}; 07 for (int x : d) q.push(x); 08 int cost = 0; 09 while (q.size() > 1) { 10 int a = q.top(); q.pop(); 11 int b = q.top(); q.pop(); 12 cost += a + b; 13 q.push(a + b); 14 } 15 cout << cost; 16 return 0; 17}
单选题:程序输出是?
考点:贪心加优先队列(M3)。
解析:合并果子 {1,2,9} → 3+12 = 15。正确答案 A。
实现要点:每次取两个最小合并。手算:1+2=3、3+9=12。
排除法:B 只算第二轮;C 先合 2+9;D 无依据。
关联 · 优先队列加贪心(F4):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 priority_queue<int, vector<int>, ______> q; // 小根堆 05 q.push(3); q.push(1); q.push(2); 06 cout << q.top(); 07 return 0; 08}
单选题:横线处应填入?(使输出为 1)
考点:优先队列填空(M4)。
解析:greater<int>——小根堆。正确答案 A。
实现要点:默认 less(大根)、greater(小根)。手算:top = 1。
排除法:B 是大根;C/D 语法错。
关联 · 优先队列回顾(F1):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // top-k:{3,1,4,1,5,9,2,6} 最大的 2 个 05 int d[8] = {3, 1, 4, 1, 5, 9, 2, 6}; 06 int k = 2; 07 priority_queue<int, vector<int>, greater<int>> q; 08 for (int i = 0; i < 8; i++) { 09 if ((int)q.size() < k) q.push(d[i]); 10 else if (d[i] > q.top()) { q.pop(); q.push(d[i]); } 11 } 12 cout << q.top() << " "; q.pop(); 13 cout << q.top(); 14 return 0; 15}
单选题:程序输出是?(最大的 2 个从小到大:9、6 的堆内升序输出 6 9?——小根堆弹出顺序 6 9)
考点:应用输出(M5)。
解析:top-2 小根堆最终 {6,9} → 输出 6 9。正确答案 A。
实现要点:k 大小的小根堆当门槛。手算:逐元素替换。
排除法:B 是降序;C/D 无依据。
关联 · 应用总表(F5):top-k 代码。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // Dijkstra 用优先队列:每次取 dist 最小的未确定点(此处演示取最小逻辑) 05 priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; 06 q.push({0, 1}); q.push({5, 2}); q.push({2, 3}); 07 cout << q.top().first << " " << q.top().second; 08 return 0; 09}
单选题:程序输出是?(dist 最小的点是 0 号距离的 1)
考点:综合(M6)。
解析:dist 最小的是 (0,1)。正确答案 A。
实现要点:pair 默认按 first 比较。手算:0 < 2 < 5。
排除法:B/C/D 无依据。
关联 · Dijkstra(F5):图论衔接。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[10] = {0, 2, 9, 4, 7, 1, 8, 3, 6, 5}; 05 int k = 4; 06 deque<int> q; 07 for (int i = 1; i <= 9; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(窗口 [1,4]=9、[2,5]=9、[3,6]=8、[4,7]=8、[5,8]=8、[6,9]=8)
考点:滑动窗口最大值(N1)。
解析:k=4 最大 9 9 8 8 8 8。正确答案 A。
实现要点:完整四步。手算:逐窗口。
排除法:B/C/D 无依据。
关联 · 滑动窗口最大值(I2):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 每日温度:{73,74,75,71,69,72} 距下一个更高温的天数 05 int t[7] = {0, 73, 74, 75, 71, 69, 72}; 06 int ans[7] = {0}; 07 stack<int> st; 08 for (int i = 1; i <= 6; i++) { 09 while (!st.empty() && t[st.top()] < t[i]) { 10 ans[st.top()] = i - st.top(); 11 st.pop(); 12 } 13 st.push(i); 14 } 15 for (int i = 1; i <= 6; i++) cout << ans[i] << " "; 16 return 0; 17}
单选题:程序输出是?(73→1、74→1、75→0、71→2、69→1、72→0)
考点:单调栈应用(N2)。
解析:每日温度距更高温天数 1 1 0 2 1 0。正确答案 A。
实现要点:递减栈记录下标差。手算:73 的下一更高是 74(差 1)。
排除法:B/C/D 无依据。
关联 · 下一个更大元素(K2):应用变体。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 deque<int> q; 05 // 用 deque 当栈用:push_back + pop_back 06 q.push_back(1); q.push_back(2); q.push_back(3); 07 q.pop_back(); 08 cout << q.back(); 09 return 0; 10}
单选题:程序输出是?
考点:deque 应用(N3)。
解析:deque 当栈——push_back 后 pop_back → back = 2。正确答案 A。
实现要点:一端当栈用。手算:1 2 3 → 弹 3 → 2。
排除法:B 是弹出的值;C/D 无依据。
关联 · 与 queue 和 stack 对比(E3):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 任务调度:{3,1,2} 排队接水总等待 = 1+3+6 = 10 05 priority_queue<int, vector<int>, greater<int>> q; 06 q.push(3); q.push(1); q.push(2); 07 long long wait = 0, cur = 0; 08 while (!q.empty()) { 09 cur += q.top(); q.pop(); 10 wait += cur; 11 } 12 cout << wait; 13 return 0; 14}
单选题:程序输出是?
考点:优先队列应用(N4)。
解析:排队接水 {3,1,2} 总等待 10。正确答案 A。
实现要点:短任务优先。手算:完成时刻 1、3、6 → 和 10。
排除法:B/C/D 无依据。
关联 · 任务调度(F5):应用代码。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[6] = {0, 1, 4, 2, 5, 3}; 05 int ans[6] = {0}; 06 stack<int> st; 07 for (int i = 1; i <= 5; i++) { 08 while (!st.empty() && a[st.top()] < a[i]) { 09 ______; // 记录答案并弹出 10 st.pop(); 11 } 12 st.push(i); 13 } 14 for (int i = 1; i <= 5; i++) cout << ans[i] << " "; 15 return 0; 16}
单选题:横线处应填入?(使输出为 4 5 5 0 0——各元素的下一个更大)
考点:填空(N5)。
解析:ans[st.top()] = a[i]——记录答案。正确答案 A。
实现要点:弹栈顶时写答案。手算:验证 4 5 5 0 0。
排除法:B 写反;C 存下标;D 无依据。
关联 · 单调栈填空(K4):同目标填空。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 // 综合:{2,1,5,6,2,3} 的下一个更大元素 05 int a[7] = {0, 2, 1, 5, 6, 2, 3}; 06 int ans[7] = {0}; 07 stack<int> st; 08 for (int i = 1; i <= 6; i++) { 09 while (!st.empty() && a[st.top()] < a[i]) { 10 ans[st.top()] = a[i]; 11 st.pop(); 12 } 13 st.push(i); 14 } 15 for (int i = 1; i <= 6; i++) cout << ans[i] << " "; 16 return 0; 17}
单选题:程序输出是?(2→5、1→5、5→6、6→0、2→3、3→0)
考点:大综合(N6)。
解析:{2,1,5,6,2,3} 下一个更大 5 5 6 0 3 0。正确答案 A。
实现要点:递减栈全流程。手算:逐个处理。
排除法:B 漏 2→3;C/D 无依据。
关联 · 下一个更大元素(K2):同法双题。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[9] = {0, 1, 3, -1, -3, 5, 3, 6, 7}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 8; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) ______; // 尾维护递减 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:横线处应填入?(使输出为 3 3 5 5 6 7)
考点:单调队列填空(O1)。
解析:尾维护弹 q.pop_back()。正确答案 A。
实现要点:递减队列尾弹。手算:验证最大序列。
排除法:B 弹头错;C/D 无依据。
关联 · 队尾维护单调性(B1):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[9] = {0, 1, 3, -1, -3, 5, 3, 6, 7}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 8; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 ______; // 插入当前下标 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:横线处应填入?(使输出为 3 3 5 5 6 7)
考点:滑动窗口填空(O2)。
解析:q.push_back(i)——插入下标。正确答案 A。
实现要点:存下标。手算:验证。
排除法:B 插头错;C 存值(不能判过期);D 无依据。
关联 · 存下标的原因(B3):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[5] = {0, 2, 1, 5, 3}; 05 int ans[5] = {0}; 06 stack<int> st; 07 for (int i = 1; i <= 4; i++) { 08 while (!st.empty() && a[st.top()] < a[i]) { 09 ans[st.top()] = a[i]; 10 ______; // 弹出栈顶 11 } 12 st.push(i); 13 } 14 for (int i = 1; i <= 4; i++) cout << ans[i] << " "; 15 return 0; 16}
单选题:横线处应填入?(使输出为 5 5 0 0)
考点:单调栈填空(O3)。
解析:st.pop()——弹出栈顶。正确答案 A。
实现要点:弹栈顶后写答案。手算:验证 5 5 0 0。
排除法:B 是插入;C 赋值错;D 无依据。
关联 · 递减栈流程(D3):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 deque<int> q; 05 q.push_back(1); 06 q.push_back(2); 07 ______; // 弹队头 08 cout << q.front(); 09 return 0; 10}
单选题:横线处应填入?(使输出为 2)
考点:deque 填空(O4)。
解析:q.pop_front()——弹队头。正确答案 A。
实现要点:四操作语义。手算:弹 1 后 front 2。
排除法:B 弹尾(front 仍 1);C/D 无依据。
关联 · deque 的四种操作(E2):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 priority_queue<int> q; // 大根堆 05 q.push(3); q.push(5); q.push(1); 06 cout << ______; // 取堆顶 07 return 0; 08}
单选题:横线处应填入?(使输出为 5)
考点:优先队列填空(O5)。
解析:q.top()——取堆顶。正确答案 A。
实现要点:priority_queue 用 top(不是 front)。手算:5。
排除法:B/C 是 deque 接口;D 返回 void。
关联 · 优先队列回顾(F1):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 priority_queue<int> q; 05 bool valid[10] = {0}; 06 q.push(5); valid[5] = true; 07 q.push(3); valid[3] = true; 08 valid[5] = false; // 5 失效 09 while (!q.empty() && ______) q.pop(); // 清理失效堆顶 10 cout << q.top(); 11 return 0; 12}
单选题:横线处应填入?(使输出为 3)
考点:延迟删除填空(O6)。
解析:!valid[q.top()]——清理失效堆顶。正确答案 A。
实现要点:取顶前判失效。手算:弹 5 后取 3。
排除法:B 反向(有效时弹);C/D 无依据。
关联 · 延迟删除(F2):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[6] = {0, 4, 2, 6, 1, 8}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 5; i++) { 08 while (!q.empty() && q.front() < i - k + 1) q.pop_front(); 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (______) cout << a[q.front()] << " "; // 窗口完整才输出 12 } 13 return 0; 14}
单选题:横线处应填入?(使输出为 6 6 8)
考点:综合填空(O7)。
解析:i >= k——窗口完整才输出。正确答案 A。
实现要点:输出条件。手算:验证 6 6 8。
排除法:B 漏 k 窗口;C 只第一个;D 无依据。
关联 · 代码框架(C5):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[6] = {0, 9, 8, 7, 6, 5}; 05 int k = 3; 06 deque<int> q; 07 for (int i = 1; i <= 5; i++) { 08 // 错误:忘了弹过期队头 09 while (!q.empty() && a[q.back()] <= a[i]) q.pop_back(); 10 q.push_back(i); 11 if (i >= k) cout << a[q.front()] << " "; 12 } 13 return 0; 14}
单选题:程序输出是?(递减数组:队头 9 永不被顶掉——忘弹过期后 9 一直"赖"在窗口外输出;正确应为 9 8 7)
考点:忘弹过期元素(P1)。
解析:递减数组 {9,8,7,6,5} 忘弹过期 → 9 一直赖着 → 9 9 9(正确 9 8 7)。正确答案 A。
实现要点:过期弹窗是必须步骤。手算:队头 9 永不被顶掉。
排除法:B 是正确值;C/D 无依据。
关联 · 单调队列忘弹过期(H1):错误示范。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int a[5] = {0, 2, 1, 5, 3}; 05 int ans[5] = {0}; 06 stack<int> st; 07 for (int i = 1; i <= 4; i++) { 08 while (!st.empty() && a[st.top()] > a[i]) { // 错误:方向反(递增栈) 09 ans[st.top()] = a[i]; 10 st.pop(); 11 } 12 st.push(i); 13 } 14 for (int i = 1; i <= 4; i++) cout << ans[i] << " "; 15 return 0; 16}
单选题:程序输出是?(方向反算出的是"下一个更小"而非"下一个更大")
考点:单调栈方向反(P2)。
解析:方向反(递增栈)算出下一个更小 1 0 3 0(正确下一个更大是 5 5 0 0)。正确答案 A。
实现要点:递减求更大、递增求更小。手算:方向对照。
排除法:B 是正确值;C/D 无依据。
关联 · 单调栈方向错(H2):错误示范。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 deque<int> q; 05 q.pop_front(); // 错误:空 deque 弹出 → 未定义行为 06 cout << "danger"; 07 return 0; 08}
判断题:空 deque 上 pop_front()/front() 是未定义行为——操作前必须判 !q.empty()。
考点:deque 越界(P3)。
解析:空 deque 弹出是未定义行为——必判空。✅ 正确
实现要点:!q.empty() 是纪律。手算:空队列无元素可弹。
排除法:无(判断题)。混淆点:未定义 = 可能不报错。
关联 · deque 空时访问(H3):错误示范。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 priority_queue<int> q; 05 bool valid[10] = {0}; 06 q.push(5); valid[5] = true; 07 q.push(3); valid[3] = true; 08 valid[5] = false; 09 // 错误:直接取 top 不检查 valid → 拿到已失效的 5 10 cout << q.top(); 11 return 0; 12}
单选题:程序输出是?(漏判失效直接取顶——拿到失效值 5;正确应先清理再取 3)
考点:延迟删除漏判(P4)。
解析:漏判直接取顶 → 拿到失效的 5(正确应先清理取 3)。正确答案 A。
实现要点:取顶前必须 while 清理。手算:5 已失效。
排除法:B 是正确值;C/D 无依据。
关联 · 延迟删除忘判(H4):错误示范。
01#include <bits/stdc++.h> 02using namespace std; 03struct cmp { 04 bool operator()(int a, int b) { return a < b; } // 错误:想建小根堆却写反 05}; 06int main() { 07 priority_queue<int, vector<int>, cmp> q; 08 q.push(3); q.push(1); q.push(2); 09 cout << q.top(); 10 return 0; 11}
单选题:程序输出是?(a < b 让大的优先——建成了大根堆;小根堆应写 a > b)
考点:优先队列比较器反(P5)。
解析:a < b 让大值优先 → 建成了大根堆,top = 3(想建小根堆应写 a > b)。正确答案 A。
实现要点:比较器返回 true 表示"a 排 b 前"。手算:3 最大在前。
排除法:B 是小根堆结果;C/D 无依据。
关联 · 优先队列回顾(F1):错误示范。
判断题:以下结论全部正确——"单调队列尾维护+头弹过期;单调栈递减求下一个更大;deque 空访问非法;延迟删除取顶前判失效;priority_queue 比较器 a>b 才是小根堆"。
考点:综合判断(P6)。
解析:五结论全对——尾维护+头弹过期、递减求更大、deque 判空、延迟删除判失效、比较器方向。✅ 正确
实现要点:数据结构板块收官章的核心自查。手算:逐条对照本章代码。
排除法:无(判断题)。混淆点:本卷(30 章)完成数据结构板块——27 线段树、28 树状数组 ST 表、29 并查集 Trie、30 单调队列优先队列。
关联 · 本章全部核心结论:收官综合判断题。