竞赛环境与代码规范
1.1 文件重定向 freopen(输入输出标准写法:freopen("xxx.in","r",stdin))
1.2 文件命名规则(严格按照题目要求,通常为小写字母)
1.3 return 0 的必要性(评测机依赖返回值判断)
1.4 栈空间限制(大数组必须开在全局,防止爆栈)
1.5 全局变量自动初始化为 $0$(局部变量不会)
1.6 数据类型范围快速判断(int 约 $2 \times 10^9$,long long 约 $9 \times 10^{18}$)
1.7 浮点数输出精度控制(cout << fixed << setprecision(2))
1.8 防卡常技巧(关闭同步流,尽量用 scanf/printf)
1.9 多组输入 while(scanf(...) != EOF) 与 while(cin >> n)
枚举算法的原子化细节
2.1 枚举定义:有序尝试所有可能性
2.2 单重循环枚举(遍历一维数组找答案)
2.3 双重循环枚举(遍历二维矩阵,如双指针暴力)
2.4 三重循环枚举(注意时间复杂度,超过 $10^8$ 会超时)
2.5 枚举范围的确定(枚举下界与上界,避免越界)
2.6 枚举的剪枝初步(如果当前前缀已不满足,提前 continue)
2.7 排列枚举(next_permutation 全排列)
2.8 子集枚举(二进制状态压缩枚举)
2.9 枚举时 break 与 continue 的边界处理
模拟算法的原子化细节
3.1 模拟定义:完全按照题意描述编写代码
3.2 时间轴模拟(用一个变量代表当前时间)
3.3 过程模拟(记录每一步的状态变化)
3.4 矩阵方向模拟(方向数组 int dx[4] = {0,1,0,-1})
3.5 边界判断(判断当前坐标是否在矩阵范围内)
3.6 周期模拟(利用取模运算处理循环节)
3.7 大规模模拟中的数据结构选择(数组 vs vector)
3.8 状态恢复(回溯模拟中的重置变量)
排序算法的实现与细节
4.1 冒泡排序(相邻交换,每次把最大数沉底)
4.2 冒泡排序的优化(设置 flag,若本轮无交换则提前结束)
4.3 选择排序(每次选择最小元素放到前面)
4.4 插入排序(将当前元素插入到前面已排序序列的合适位置)
4.5 快速排序的 partition 思想(虽然竞赛直接用 sort)
4.6 sort 函数的底层原理(Introspective Sort,结合快排、堆排、插排)
4.7 sort 自定义比较规则(cmp 函数返回值:a<b 升序,a>b 降序)
4.8 sort 对结构体排序(按照某个成员排序)
4.9 stable_sort 稳定排序(相等元素保持原顺序)
4.10 排序+去重(unique 配合 erase)
4.11 时间复杂度的感性认知($O(n^2)$ 只能处理 $5000$ 以内)
查找算法与二分细节
5.1 顺序查找($O(n)$,无特殊要求)
5.2 二分查找的前提(严格单调递增或递减)
5.3 二分区间的开闭写法(左闭右闭 [l, r] vs 左闭右开 [l, r))
5.4 二分查找整数(求第一个大于等于 target 的位置 lower_bound)
5.5 二分查找整数(求第一个大于 target 的位置 upper_bound)
5.6 手动实现 lower_bound(while(l<r) { mid = l + (r-l)/2; } 防溢出)
5.7 二分答案(对于可判断可行性的最优值问题,如最大化最小值)
5.8 二分浮点数(while(r-l > eps) 精确到 $10^{-6}$)
5.9 STL 二分库函数(lower_bound, upper_bound, binary_search)
递归与递推的实现细节
6.1 递归三要素(终止条件、递推公式、返回值)
6.2 递归的执行顺序(先递后归,即先深入到底再逐层返回)
6.3 递归调用栈(函数调用帧入栈与出栈)
6.4 尾递归优化(C++编译器一般不强制优化,避免深递归)
6.5 斐波那契递归的指数爆炸(需要记忆化优化)
6.6 记忆化搜索实现(数组记录已计算状态)
6.7 递推公式的边界处理(防止数组下标 $-1$)
6.8 递推中的滚动数组优化(只保留前两个状态减少空间)
深度优先搜索(DFS)的代码模板细节
7.1 DFS 的经典模板(void dfs(状态参数) { if(终止) ...; for(所有可能选择) { 修改状态; dfs(下一层); 恢复状态; } })
7.2 状态表示设计(坐标、已选数量、当前和)
7.3 递归终止条件(到达边界或找到答案)
7.4 回溯恢复现场的重要性(引用传递参数时必须手动恢复)
7.5 剪枝的分类(可行性剪枝 vs 最优性剪枝)
7.6 奇偶性剪枝(奇偶性判断提前排除不可能路径)
7.7 路径搜索中的 vis 数组标记(防止重复走回头路)
7.8 全排列 DFS 与组合 DFS 的区别(是否需要记录 start 索引)
广度优先搜索(BFS)的代码模板细节
8.1 BFS 的经典模板(queue + while(!q.empty()))
8.2 BFS 的状态入队(每次弹出队首,扩展子状态入队)
8.3 BFS 的层次遍历(记录当前队列大小 size = q.size())
8.4 BFS 最短路特性(第一次到达即为最短,边权必须为 $1$)
8.5 BFS 中的距离数组(dist[][] 或 unordered_map)
8.6 BFS 的判重(必须将访问过的状态立即标记,防止重复入队)
8.7 三维空间 BFS($6$ 个方向或更多)
8.8 多源 BFS(将所有起点同时入队,求最近源点距离)
基础数据结构实现(栈与队列应用)
9.1 手写栈(数组模拟,top 指针)
9.2 手写队列(循环队列,front 与 rear 指针)
9.3 括号匹配(遇到左括号入栈,右括号弹出匹配)
9.4 后缀表达式求值(遇到数字入栈,遇到运算符弹出两个计算)
9.5 滑动窗口中的单调队列(维护窗口内最值)
9.6 单调栈解决下一个更大元素问题
算法策略(前缀和与差分)
10.1 前缀和定义(pre[i] = pre[i-1] + a[i])
10.2 前缀和查询区间和([l, r] 的和 = pre[r] - pre[l-1])
10.3 二维前缀和公式(sum[i][j] = a[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1])
10.4 二维前缀和查询((x1,y1) 到 (x2,y2) = sum[x2][y2] - sum[x1-1][y2] - sum[x2][y1-1] + sum[x1-1][y1-1])
10.5 差分定义(diff[i] = a[i] - a[i-1])
10.6 差分区间加([l, r] 加 $k$ -> diff[l] += k, diff[r+1] -= k)
10.7 差分还原数组(对 diff 求前缀和)
10.8 二维差分矩阵操作
贪心策略的实现细节
11.1 贪心正确性的前提(问题具有最优子结构)
11.2 排序贪心(按某个关键字排序,如按结束时间排序安排活动)
11.3 优先队列贪心(用小根堆维护当前最优选择)
11.4 取巧贪心(局部最优解即全局最优解,注意数学证明)
时间复杂度与空间复杂度的计算
12.1 常见复杂度曲线($10^6$ 内 $O(n)$,$10^7$ 内 $O(n \log n)$,$10^8$ 内 $O(n)$ 需优化)
12.2 空间限制换算($256\text{MB}$ 大约可开 int a[6e7])
12.3 避免递归爆栈(递归深度 $10^5$ 可能导致段错误)
— 2026年7月15日