学习方法

CSP-J 学习指南:怎样把练习变成能力

快码编程 · 发布于

练习不是把“做过的题”越堆越多,而是逐渐看懂不同题目背后的结构。下面是一条学习建议,不代替官方赛事规则或考试大纲。

先判断:卡在读题、实现,还是方法?

面对一道没做出来的题,先不要马上看完整题解。尝试把卡点说得更具体:是没有理解要输出什么,还是已经会手算但写不出程序?是程序有错误,还是方法在大数据上太慢?不同卡点需要不同练习。

用一个例子理解“从暴力到优化”

给定一列整数,回答若干次提问:第 l 个数到第 r 个数的和是多少?

例如数列是 3, 1, 4, 2,询问第 2 到第 4 个数,答案是 1 + 4 + 2 = 7。

最直接的办法是每次把对应区间重新加一遍。少量查询时,这个办法很清楚,也适合做一个验证答案的小程序。若每次都扫描很长的区间,而查询次数也很多,就会重复计算大量相同内容。

先观察前缀的总和:前 1 个数是 3,前 2 个数是 4,前 3 个数是 8,前 4 个数是 10。要取第 2 到第 4 个数的和,只需用“前 4 个数的和”减去“前 1 个数的和”,得到 10 − 3 = 7。

记 S[k] 为前 k 个数的总和,S[0] = 0,那么区间和是 S[r] − S[l − 1]。为什么成立?前 r 个数可以分成互不重叠的两部分:前 l − 1 个数,以及第 l 到第 r 个数。减去前一部分,恰好留下后一部分。

如果数列不变,预处理前缀和需要 O(n) 时间,每次查询只需要 O(1) 时间。若题目允许修改数列,原来的前缀和就可能失效,不能不加判断地照搬这个方法。

按“能解释什么”安排练习

  1. 基础阶段:能独立读写输入输出,正确实现分支、循环、数组和字符串处理。
  2. 直接方法阶段:能用模拟、枚举、排序等方法解决问题,并估计时间复杂度。
  3. 结构观察阶段:能指出重复计算、单调性或局部规律,再据此学习前缀和、二分、搜索等方法。
  4. 综合阶段:在新题中选择方法,说明正确性,并检查数据范围和边界。

一次练习的完整闭环

先独立读题和取例,保留自己的初始思路;完成实现后,用样例、边界和自己构造的数据验证;如果参考了提示或题解,关掉参考材料,再用自己的话重建推导并重新实现。

复盘时,至少记录一个“迁移线索”:例如“区间查询很多、数列不变,我应当考虑能否先做预处理”。线索比单独记住“这题用前缀和”更容易在陌生题中发挥作用。

不要用通过数量代替理解

如果换一组数据就说不清程序会怎样执行,或者无法解释一个关键判断为什么正确,那么还需要回到例子和论证。稳定的能力来自理解、验证与复盘,不来自对题解代码的熟悉。