L03 复杂度、STL 与模型复盘

从“这题用什么容器”开始,训练数据范围、容器复杂度、模型识别三件事。

一、先回答问题

结论

STL 不是背函数名,而是根据需求选维护结构:去重计数、先进先出、动态最值、连续下标,各有固定工具。

教学安排

用 P1271 看计数与排序,用 P1540 看队列模拟,用 P2678 只做二分答案识别。

二、本节知识点地图

知识点学生要会什么课堂检查
STL 容器用途会选 vector/queue/set/map/priority_queue容器选型题
STL 复杂度知道常用操作量级口答复杂度
计数排序知道编号范围小时能开桶P1271 手推
队列模拟维护顺序和是否存在P1540 状态表
方向数组统一遍历 8 个方向P2670 九宫格
二分答案识别说清 check 和单调性P2678 口答

三、概念讲清楚

需求容器复杂度
连续下标vector访问 O(1)
先进先出queue入队/出队 O(1)
动态最值priority_queue插入/删除 O(log n)
有序去重/计数set/mapO(log n)

四、书籍例子:STL 不是背函数

CP4 · Andy's First Dictionary

读入文本,提取单词,去重并按字典序输出。`set<string>` 同时解决“去重”和“排序”,这就是容器选型的价值。

洛谷教材 · 扫雷 P2670

模拟题不难在算法,而难在边界。方向数组 `dx/dy` 可以把 8 个方向统一成一个循环,避免长串 if-else。

五、互动演示:容器选型

选择一个场景
先选一个场景,学生要说出容器、复杂度和常见坑。

六、自己选答案

问题 1

P1540 机器翻译最自然的维护结构是什么?

问题 2

P2678 跳石头今天要先做到什么程度?

七、样例精讲:三道题串起来

题目模型课堂重点作业要求
P1271计数 / 排序sort 和桶的取舍蛋* 必做
P1540队列模拟queue 和 set 同步全员必做
P2678二分答案答案范围 + check丁* 限时写

八、二分答案从 P2678 入门

先不背模板,先会说 check

猜一个最短跳跃距离 x,从左到右扫描石头。如果当前石头和上一块保留石头的距离小于 x,就删掉当前石头。若删除数不超过 m,说明 x 可行。

单调性:x 越大,要求越严格,越不容易可行。

九、当堂练习与课后习题

类型题目/任务要求
当堂练习容器选型 5 题说出容器和复杂度
当堂练习P1540 容量=2 状态表queue/set 同步
蛋*作业P1271、P1540每题写模型判断
丁*作业P1540、P2678、P1182 check 设计P2678 限时 30 分钟

十、课堂验收

下课前必须答出

1. set/map 分别适合什么? 2. priority_queue 为什么为 Dijkstra 铺垫? 3. P1540 为什么不能只用 queue? 4. 扫雷为什么适合方向数组? 5. P2678 的 check(x) 检查什么?

十一、C++14 片段

#include <bits/stdc++.h>
using namespace std;

priority_queue<int, vector<int>, greater<int>> pq;
map<int, int> cnt;
queue<int> q;
set<int> inMemory;

for (int x : words) {
    if (!inMemory.count(x)) {
        q.push(x);
        inMemory.insert(x);
        if ((int)q.size() > capacity) {
            inMemory.erase(q.front());
            q.pop();
        }
    }
}

读代码重点:P1540 的关键不是 queue 本身,而是 queue 和 set 必须同步维护。