C++ 的优势不是“语法更复杂”,而是对类型、性能和底层结构控制更强。进入图算法、动态规划、优先队列和高数据量场景后,C++ 往往更稳。
适用场景
- 路径规划与资源调度题。
- 需要优先队列、图搜索、动态规划的题目。
- 数据规模较大、时间限制较紧的题目。
- 需要严格控制整数类型、数组空间和常数开销的题目。
推荐代码骨架
#include <bits/stdc++.h>
using namespace std;
void solve() {
// 读入
// 处理
// 输出
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
为什么推荐这套骨架
- 输入输出速度稳定。
- 结构清晰,便于拆函数。
- 复盘时容易定位逻辑区段。
常用容器与适用场景
vector:顺序存储、动态数组、图邻接表。string:字符串处理。pair:表示坐标、边、双关键字。map/unordered_map:映射关系、频次统计。set/unordered_set:去重与访问判断。queue/deque:流程模拟、BFS。priority_queue:最短路、资源调度、贪心选择。
模板选择建议
排序模板
sort(items.begin(), items.end(), [](const auto& a, const auto& b) {
if (a.score != b.score) return a.score > b.score;
if (a.cost != b.cost) return a.cost < b.cost;
return a.name < b.name;
});
排序题最关键的是把主关键字和 tie-break 写全。
BFS 模板
queue<int> q;
vector<int> dist(n, -1);
dist[start] = 0;
q.push(start);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v : graph[u]) {
if (dist[v] == -1) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
}
最短路模板
using PII = pair<long long, int>;
priority_queue<PII, vector<PII>, greater<PII>> pq;
vector<long long> dist(n, INF);
dist[start] = 0;
pq.push({0, start});
适用于带权图和路线成本类题。
类型控制建议
整数类型
- 计数、小范围下标通常可用
int。 - 金额、累计和、路径总代价、乘法结果建议优先考虑
long long。 - 当题面涉及“两个较大数相乘”时,先估算范围,再决定类型。
浮点数
- 只在确实需要时使用
double。 - 输出时要注意
fixed << setprecision(k)。 - 比较浮点数大小时要小心精度误差。
C++ 写题的五步法
- 先确认数据规模,决定容器和算法级别。
- 先写清楚结构体或数据表示。
- 先完成主流程,再补细节优化。
- 对所有数组、容器和状态做边界检查。
- 最后验证类型、输出格式和复杂度。
常见错误
下标与内存错误
- 数组或
vector越界。 - 网格四方向访问时漏掉边界判断。
resize后误以为已有有效值。
初始化错误
- 变量未初始化。
- 最短路、DP、最值数组初值设置错误。
- 多组数据时忘记清空容器。
类型错误
int溢出。- 比较器返回条件不完整,导致排序结果不稳定。
size()返回无符号类型,与int混用时产生警告或逻辑问题。
逻辑错误
- 优先队列中旧状态未丢弃。
- BFS 中访问标记时机错误。
- 动态规划转移缺少边界状态。
自检清单
- 是否使用了合适的整数类型。
- 是否存在越界访问风险。
- 多组数据时是否重置了状态。
- 排序规则是否写全。
- 是否对极小样例和极大样例都做了检查。
面向教学的建议
- 初学 C++ 时,不要一开始追求写法花哨,先强调结构清晰。
- 让学生养成“先写数据结构定义,再写算法逻辑”的习惯。
- 对带训人员,建议准备统一模板:读入模板、图模板、DP 模板、调试模板。
与 Python 的协同关系
- Python 适合快速验证思路。
- C++ 适合把经过验证的思路做成更稳的高性能实现。
- 最有效的训练方式通常是:先用 Python 建模,再用 C++ 严格复现。