1. 先破除一个最大的心理障碍CSP-J考的不是“高端算法”总有家长和学生跑来问我CSP-J的算法到底有多难是不是得先把大学的《算法设计与分析》啃完我印象特别深有个家长拿着手机指着一串热搜词问我“你看这些‘粒子群算法’‘深度学习算法’‘hcaptcha逆向算法’‘3DGS算法’是不是CSP-J都得学”我当时就笑了这些名词放在一起确实唬人但CSP-J真不需要碰它们。竞赛圈有句老话CSP-J考的是“基础算法”不是“科研算法”。它的全称是非专业级软件能力认证入门级定位就是给初中生、小学生检验编程基本功的考察范围在CCF发布的《NOI大纲》里写得明明白白模拟、枚举、排序、二分、贪心、搜索、简单动态规划、基础数学就这些。为什么我要先说这个因为我在实际接触考生的过程中发现真正劝退大多数人的不是题目难度而是信息差和焦虑感。你搜一次“CSP-J”推荐流里就会混进各种高级算法热词这些词有的来自人工智能领域有的来自工业控制领域有的干脆是逆向工程方向跟入门级算法认证八竿子打不着。一个刚学完C语法的小朋友看到这些词本想搜备考资料结果被一堆硕士博士论文级别的名词吓退了这是最可惜的。1.1 为什么热搜会给你制造焦虑你仔细观察那些网络热词会发现一个规律真正属于CSP-J考点的词比如“二分算法”“冒泡排序算法c”“算法流程图”“数据结构与算法”“堆排序算法”“KMP算法”会被淹没在“粒子群算法”“NSGA-II算法”“混音算法”“PID算法”“深度学习算法”“hcaptcha逆向算法”这些完全无关的词里。搜索引擎和推荐系统并不理解CSP-J的考试大纲它只看到“算法”两个字于是把所有带“算法”的内容一股脑推给你。这里顺便说个判断方法凡是在CSP-J备考语境下出现“神经网络”“粒子群”“强化学习”“逆向工程”这类词基本可以判定为噪音。倒不是说这些技术不好而是它们与CSP-J的考察方向完全不重合。CSP-J需要的是能在考场上手写出来、能分析时间复杂度的基础算法而不是需要调参、需要大量前置知识的前沿算法。备考时一定要学会“屏蔽噪音”以官方大纲和历年真题为准别被推荐流带偏节奏。1.2 初赛与复赛的分工笔试考“看懂的算法”上机考“写对的算法”CSP-J全年有两轮认证第一轮是笔试也叫初赛第二轮是上机编程复赛。这两轮对算法的考察方式完全不同很多人没搞清楚就开始猛刷题方向就容易偏。第一轮笔试题型包括单选题、阅读程序题、完善程序题。它重点考的是“能不能看懂算法”给你一段排序代码你要能判断它的时间复杂度和功能给你一个递归函数你要能口算出输出结果给你一个半成品程序你要能补全关键逻辑。说白了考的是算法阅读能力和手算模拟能力。2025年的第一轮刚过去没多久网上到处是真题解析很多估分不理想的孩子不是不会写代码而是不会“人工执行程序”一遇到循环和递归就晕。第二轮复赛是纯粹的代码能力测试4道编程题几百个字符的代码量考的是算法设计、边界处理、调试技巧。这里算法就变成了“工具”你得知道什么时候该用二分答案、什么时候该用BFS、什么时候该上背包DP。复赛判题只看程序运行结果不看过程所以写不写得对、调不调得通才是关键。所以备考CSP-J的算法要两条腿走路笔试练“手算模拟程序”的能力上机练“把思路变成能跑通的代码”的能力。后面我会分章节展开。2. 人话版的CSP-J算法清单哪些必须掌握哪些可以后置很多家长喜欢问我一个问题CSP-J考纲里的算法那么多哪些是重点哪些可以战略性放弃我的回答是CSP-J的算法面其实很窄窄到哪怕你只掌握六类基础算法也能覆盖复赛80%以上的题目。与其广撒网去学各种“看起来很厉害”的算法不如把真正高频考点的底层逻辑吃透。2.1 必须熟练掌握的“基础六件套”第一件模拟与枚举。这是CSP-J的绝对主体复赛几乎每年都有一道纯模拟题。模拟就是照着题目描述一步步执行不考智商考细心枚举就是按顺序尝试所有可能配合剪枝使用。很多孩子觉得模拟题“没技术含量”结果一到考场就栽在细节上——循环边界差一位、忘记开long long、题目说的“取模”没做。这部分练的是代码实现精度没有什么技巧就是多写多踩坑。第二件排序。排序算法本身是考点但更重要是排序这个操作在解题中的运用。CSP-J笔试喜欢考冒泡排序的优化版本、选择排序的交换次数以及排序的稳定性复赛里sort函数无处不在你得知道什么时候需要自定义比较函数、什么时候排序能降低问题复杂度。二分的基础其实就建立在有序数组上所以排序算是整个算法体系的底座。第三件二分。二分包括二分查找和二分答案两块。二分查找是在有序数组中找目标值边界处理是重点二分答案则是把“求最优解”转换成“判断某个答案是否可行”是复赛里的高分利器。第二大题如果出现“最大值最小”或“最小值最大”的描述八成就是在暗示你用二分答案。第四件搜索。DFS深度优先搜索和BFS广度优先搜索是CSP-J复赛的常客。前者配合回溯和剪枝解决排列、组合、迷宫类问题后者擅长处理最短步数、连通块数量、层次遍历类问题。搜索是很多孩子第一次接触“算法思维”的地方也是区分入门者和进阶者的分水岭。第五件动态规划入门。CSP-J的DP考得很基础线性DP、01背包、完全背包、最长上升子序列、最长公共子序列就这些。很多孩子一开始看不懂状态转移方程我的建议是先背熟背包模板再反复手推几道经典题慢慢就能理解“状态”和“转移”的含义。第六件基础数学。包括质数筛、最大公约数、最小公倍数、快速幂、高精度运算。这些知识点单独考不会太难但经常作为题目的内层逻辑出现。比如2021年的“分糖果”、2019年的“加工零件”表面是模拟和图论底层的数学性质才是解题关键。2.2 依据大纲的优先级排序为了让备考的同学心里有数我把自己整理的优先级表放在下面。请注意“了解”不等于不学而是说在时间紧张的情况下可以往后放。优先级算法知识点考察形式建议投入时间必须熟练掌握模拟、枚举、排序、二分、DFS/BFS、01背包、质数筛、GCD/LCM笔试复赛高频占总复习时间60%建议掌握贪心、分治归并排序、前缀和与差分、最短路Dijkstra/Floyd、并查集复赛中低频笔试阅读题可能涉及占总复习时间30%了解即可KMP字符串匹配、最小生成树、拓扑排序、状态压缩复赛极少直接考笔试偶尔以阅读题形式出现占总复习时间10%完全不用学粒子群、神经网络、各类工业/逆向算法不考02.3 那些在CSP-J里出现很少的算法我见过最离谱的备考方式是有人花一个月去研究KMP算法理由是“字符串处理很重要”。KMP在CSP-S里是常见考点但在入门级里出场率极低笔试偶尔在阅读程序题里出现一次会做固然好不会也不影响拿奖。同样的道理适用于堆排序——堆排序本身不是必须手写的考点因为C的STL里已经有priority_queue你需要的是会用而不是会造轮子。真正应该直接忽略的是粒子群算法、NSGA-II、强化学习、逆向算法这类“热搜算法”。它们不属于CSP-J甚至不属于任何一个高中竞赛考点纯属推荐流制造的噪音。备考时间就那么几个月你把时间花在这些地方那就真的和大奖无缘了。判断一个算法学不学标准只有一个翻开近五年真题看看它出现过几次。出现在真题里的才值得你花时间。3. 初赛算法题怎么考识别、模拟、套模板第一轮笔试的三种题型里单选题考查算法概念的比重不大真正拉开差距的是阅读程序题和完善程序题。这两类题说白了就是考两件事你能不能“看懂”一段程序你能不能“补全”一段程序。很多平时刷题很猛的孩子在这里翻车因为他们习惯了“运行代码看结果”从来没有练过“用草稿纸人工执行代码”。3.1 流程图题和阅读程序题的算法识别初赛中偶尔会出现算法流程图题给你一张画着菱形判断框和矩形处理框的图问你这段流程实现的是什么功能。我的解题顺序是先找变量名再找循环出口最后看条件分支。变量名往往是破案关键——sum是累加、max/min是求最值、cnt是计数、flag是标记位。比如流程图里出现“cnt”放在某个判断条件的内部那大概率是统计满足条件的个数出现“交换a[i]和a[j]”那基本就是在排序。阅读程序题就更讲究技巧了。拿到一段程序后不要立刻逐行死读先通读一遍从整体上判断它的功能。我给学生的建议是“代入特例法”如果程序处理一个数组就自己造一个长度为3或4的小数组然后跟着代码一步步算如果是递归函数就选一个n2或n3的小规模画出递归调用树。比如下面这段二分代码就是初赛的经典考法int l 0, r n - 1; while (l r) { int mid (l r 1) / 2; if (check(mid)) l mid; else r mid - 1; } cout l endl;看到这种结构第一反应应该是这是“在可行域中寻找最大值”的二分答案模板mid用上取整lr1/2是为了防止当l和r相邻时出现死循环。你要是能识别出这是模板后面的问题基本都能答对。相反如果你没见过这个模板考试现场临时推边界很难推对。3.2 用二分查找和排序原题演示“手算模拟”我们再拿排序来演示一遍“手算模拟”的过程。初赛喜欢考冒泡排序的优化写法典型代码长这样for (int i 1; i n; i) { bool flag false; for (int j 1; j n - i; j) { if (a[j] a[j 1]) { swap(a[j], a[j 1]); flag true; } } if (!flag) break; }如果题目问你“这段代码排序后数组是什么样”别傻乎乎重新排序你只需要知道每轮冒泡会把当前范围内最大的数放到末尾而且如果某轮没有发生交换就提前结束。给你数组{5, 1, 4, 2, 8}第一轮下来最大数8沉底第二轮下来4冒泡到倒数第二的位置第三轮下来2也归位实际上第三轮结束后还有个1排在第一位到第四轮检查时发现没有交换就break了。整个排序过程是能说清楚的只看你愿不愿意动手在草稿纸上画。手算模拟程序是初赛的硬功夫没有捷径只能靠刷题练。我的建议是备考初赛时找近五年的阅读程序题每一道题都自己在草稿纸上跑一遍跑完再对答案不要偷懒直接看解析。练上二三十道你对循环、递归、数组下标的感觉会完全不一样。3.3 完善程序题从空着不会到有章法完善程序题是初赛里平均分最低的题型因为它考的不仅是“看懂程序”还得“理解作者的思路并补全空缺”。很多人一看到空格就慌其实这类题解题套路特别固定。第一步通读一遍程序了解它要做什么。代码通常不会太长变量名和注释会透露很多信息。第二步看空格附近的代码逻辑。比如二分答案的完善题空格处往往就是mid的赋值、check条件的判断、或边界l/r的移动搜索题的完善题空格处往往是递归终止条件和状态标记。第三步才是代入数据验证。比如完善程序里有一段int mid (l r) 1; // 空格候选点 if (a[mid] x) r mid; else l mid 1;那这道题八成是在实现“查找第一个大于等于x的位置”而不是普通的相等判断。你要是不理解二分查找的多种变体很容易在“到底是rmid还是rmid-1”上出错。完善程序题的备考方法很简单把近五年的真题全部做两遍以上。第一遍像考试一样限时完成第二遍做完后对着答案逐行分析把每道题用到的核心算法整理到错题本上。做完你会发现完善程序题翻来覆去就考那几个模型二分、归并、DFS、背包、前缀和、质数筛。这些模型你本来就会写代码再认认真真分析几遍“半成品程序”拿分就水到渠成了。4. 复赛上机用“暴力→优化”的思维链拿分复赛的4道题难度是递增的第一第二题通常考验基础算法第三题开始有思维难度第四题往往是综合题。但在我的经验里复赛拿分的关键不是“做出压轴题”而是“把该拿的分稳稳拿住”。这需要一套完整的读题→暴力→优化→正解的思维链。4.1 P5663 加工零件一道把BFS和奇偶性结合的例子先看2019年复赛的“加工零件”这道题。题目大意是有n个工人和m条生产线边1号工人能生成原材料。每个工人生产第L个零件时需要一个相邻工人生产第L-1个零件当L1时相邻工人直接提供原材料。然后有q个询问每个询问给一个工人编号a和需要的零件层数L问1号工人是否需要提供原材料。这题拿到手如果你真去模拟生产流程就傻了因为询问次数可能很多每层都可能把图遍历一遍。正确思路是转化为图论问题从工人a出发是否存在一条长度恰好为L的路径能够到达1号工人。为什么可以这样转化因为生产第L层的零件本质上就是沿着生产线向前一层传递传L次之后落在哪个点那个点就要提供原材料。但这里还有一个隐藏的坑路径长度“恰好为L”不等于“最短路径长度为L”。因为图里如果有一条长度为L的路径完全可以在某条边上往返走两步让路径变长而奇偶性不变。所以真正要判断的是从1号到a是否存在一条“长度≤L且奇偶性与L一致”的路径。那怎么求呢用BFS求从1号出发到每个点的最短奇数距离和最短偶数距离。BFS为什么要维护两个距离因为在无权图中BFS第一次访问到某个点的路径一定是最短的但最短奇路径和最短偶路径可能不同。你需要跑两套距离数组或者用“分层图”的思路把每个点拆成奇层和偶层。做一次BFS预处理每个询问就能O(1)回答。这道题的思维链条是读懂题意→抽象成图上路径问题→发现奇偶性规律→用BFS预处理。它完美展示了复赛题“看起来复杂拆开就是基础算法组合”的特点。4.2 P7909 分糖果用数学推导省掉模拟2021年复赛的“分糖果”就更典型了这题我愿称之为“数学思维的胜利”。题目让在[L, R]区间里选一个整数x使得x mod n最大。第一反应当然是从L到R枚举一遍取最大值但L和R的范围可能非常大暴力枚举必然超时。这时候要停下来想数学性质。取模的余数范围是0到n-1如果区间长度R-L1不小于n那么这段区间里必然存在一个数满足余数为n-1答案直接就是n-1。如果区间长度小于n再看L/n和R/n是否相等如果它们相等说明整个区间落在同一个“完整数段”内余数随x单调递增最大值就是R mod n如果它们不相等说明区间跨过了n的整数倍点那么从L到下一个n的倍数之前余数是递增的到下一个倍数时余数归零后面再逐渐涨。但别忘了由于区间长度小于n跨过归零点后余数再涨也很难超过n-1而L mod n这一侧可能就能取到比较大的值。综合起来答案如果是R mod n或者n-1中的一个具体判断条件可以写成long long ans; if (R - L 1 n) ans n - 1; else if (L / n R / n) ans R % n; else ans n - 1;我见过大量考生在这题上栽跟头不是不会枚举而是被数据范围吓住了不敢往数学方向想。这给我们的启示是复赛拿到题先别急着写代码花两分钟想想题目变量的数学含义往往比直接暴力省事得多。4.3 高频模板代码二分、前缀和、DFS、01背包复赛考场上时间是有限的能现场推理的题目是少数大多数题目需要你“条件反射”般地写出模板框架。下面这几个模板我建议你背到肌肉记忆的程度。二分答案模板求满足条件的最大值int l 0, r 1e9, ans 0; while (l r) { int mid (l r) / 2; if (check(mid)) { ans mid; l mid 1; } else { r mid - 1; } }这个写法用ans单独保存答案避免边界条件混乱适合考场上调试。如果你想写“左闭右开”风格的二分那就要注意mid的上取整写法两种风格选一种自己习惯的千万不要混用。前缀和与差分for (int i 1; i n; i) { sum[i] sum[i - 1] a[i]; } // 区间和 query(l, r) sum[r] - sum[l - 1]这个模板本身极其简单但它的应用场景非常广凡是涉及区间和、矩阵和的题都能用。复赛第二题经常就是前缀和的朴素应用加一点小变形。DFS万能搜索框架void dfs(int dep) { if (dep n) { // 得到一组完整解处理或记录 return; } for (int i 1; i n; i) { if (!used[i]) { used[i] true; a[dep] i; dfs(dep 1); used[i] false; } } }这个框架解决全排列、组合枚举、部分搜索类问题是复赛的“保分利器”。记忆重点在于递归终止条件、状态标记数组、回溯时释放标记。01背包for (int i 1; i n; i) { for (int j V; j w[i]; j--) { f[j] max(f[j], f[j - w[i]] v[i]); } }注意内层循环必须从大到小倒序遍历容量这样才能保证每个物品只被选一次。如果写成从小到大那就变成完全背包了这是考场上最常见的翻车点。这些模板背下来只是第一步关键是知道什么时候用。我的建议是平时做题时养成习惯每写出一个模板就在代码旁边用注释标出“这题考的是XXX算法的应用”慢慢形成“见题识算法”的直觉。5. 备考路线的取与舍半年怎么安排才不慌CSP-J备考最怕的不是时间不够而是方向错了还特别努力。有人天天刷难题怪题结果基础题不稳有人初一才开始学C两年后照样拿省一。归根结底这是一场“范围有限的基础算法考试”谁规划得好、执行到位谁就能赢。5.1 时间线从语法入门到真题冲刺如果你从零基础开始准备大概需要半年时间。我把时间线分成五个阶段每一周都要有明确的验收标准。阶段时间核心任务验收标准语法入门第1-6周变量、分支、循环、数组、字符串、函数能独立写完洛谷入门题单前30题基础算法第7-14周模拟、枚举、排序、二分、前缀和洛谷【算法2-1】【算法2-2】题单刷完搜索与DP第15-20周DFS、BFS、回溯剪枝、01背包、线性DP能写出全排列、迷宫最短路、背包问题初赛冲刺第21-24周做近五年初赛真题精读阅读程序和完善程序第一轮估分稳定在70分以上复赛冲刺第25-28周复赛真题限时模拟、错题复盘、补漏4道题中稳稳做出2道第3道有思路每周安排建议是周中每天1小时周末集中半天刷题。关键是“持续”不要突击。我见过太多孩子暑假猛刷一周开学后两个月不碰代码再回来手就生了。5.2 哪些算法可以先不学哪些必须“肌肉记忆”按CSP-J的得分性价比排序第一梯队是模拟、枚举、排序、二分、DFS/BFS这五个必须达到“闭着眼睛都能写”的程度。第二梯队是前缀和、差分、01背包、贪心这类算法通常作为题目的一环出现需要熟练掌握但不需要做太多偏题怪题。第三梯队是并查集、最短路、高精度、质数筛这些知识在部分年份的题目里会出现建议学透但不必追求难题。KMP、线段树、最小生成树这些如果时间充裕可以了解但不是主流考点。反过来说最应该戒掉的心态是“我要把所有算法都学完才敢上考场”。有些同学刷到排序觉得快排手写太难不学完不敢碰二分刷到二分又担心遇到实数二分调不干净干脆跳过。这种完美主义在CSP-J备考里非常致命。正确的做法是先把高频算法练到滚瓜烂熟再按照真题的指引去补充低频知识点。你翻开十年真题看复赛第三、四题的算法上限也就是“图论BFS动态规划”根本不会超纲考你一个高级数据结构。5.3 刷题与总结的方法错题本、题单、模拟赛很多孩子刷题数量不少但成绩提升不明显问题出在“从不总结”。我比较推荐“一题三看”做一遍、看一遍题解思路、隔一周再做一遍。每道题做完在题目旁边写一行tag比如“考的是二分答案贪心check”“考的是BFS分层求奇偶最短路”“考的是区间前缀和变形”。坚持30道题后你会惊讶地发现CSP-J题目类型就那么几类到时候看到新题脑子里会自动把它归类到熟悉的套路里。错题本别抄代码只记三类信息一是题目链接二是我的错误原因超时边界题意理解错三是正确思路的一句话总结。考前看错题本比刷新题有用得多它能精准提醒你容易在哪里丢分。初赛备考要额外注意“阅读程序题”和“完善程序题”的限时训练每道题控制在8-10分钟不会就跳过别在一道题上耗到时间耗尽。复赛备考每周至少完整打一场模拟赛按真实考场规则来不翻书、不查资料、连续3个半小时结束后认真复盘分数是怎么丢的。我见过不少学生CSP-J败给的不是算法难度而是信息差和焦虑。有人花两个月研究根本不考的高级算法有人天天刷难题但连枚举都写不稳还有人只看书不敲代码一到考场就是“眼睛会了手不会”。如果你能把本文列出的这些基础算法老老实实吃透把近五年真题认认真真刷完拿奖没有想象中那么难。最后分享一个小技巧从今天开始每做一道题在题目旁边写一行字——这题考的是哪个算法用了什么套路坚持30道题之后你会对CSP-J的算法范围形成一种非常准确的直觉考场上用到哪个模板、先写哪段代码基本都不需要犹豫了。