CSDN编程挑战赛稳进Top10%的7个刷题技巧,最后一个90%的人不知道!
2026/8/9 15:49:07 网站建设 项目流程

前言

这篇文章我把自己从青铜到AK踩过的坑、总结的技巧全部分享出来。

全文7000字,附可直接套用的代码模板,建议收藏后慢慢看。


一、先读题 30 秒,胜过写码两小时

1.1 你真的会读题吗?

很多同学拿到题就开始写,写了一半发现理解错了题意,推倒重来 ——时间就这么没的。

我的读题三步法:

步骤做什么关注什么
第 1 遍速读搞清楚 "输入什么、输出什么"数据范围、时间限制
第 2 遍精读找出约束条件和坑点"恰好"、"最多"、"至少"
第 3 遍验证用样例反推题意边界样例、特殊样例

1.2 实战案例

看这道题的描述:

给定一个数组,找出和最大的连续子数组,返回其最大和。

很简单对吧?LeetCode 第 53 题,经典动态规划。

但如果题目改成:

给定一个数组,找出和最大非空连续子数组,返回其最大和。数组长度≥1。

有区别吗?有。前者隐含了可以选空数组(和为 0),后者明确了非空。当数组全是负数时,答案完全不同。

一个词的差别,就是 0 分和 100 分的距离。


二、数据范围决定算法选型

2.1 这是最重要的技巧,没有之一

比赛时拿到题,先看数据范围,再想算法

数据范围就是出题人给你的 "暗示":

数据规模可选时间复杂度对应算法
n ≤ 20O(2^n)状态压缩、暴力搜索
n ≤ 100O(n^3)Floyd、区间 DP
n ≤ 1000O(n^2)普通 DP、双循环枚举
n ≤ 10^5O(n log n)排序、二分、线段树、堆
n ≤ 10^6O(n)贪心、双指针、前缀和
n ≤ 10^9O(log n)数学公式、快速幂、矩阵快速幂

2.2 举个例子

题目:求数组中第 K 大的数。

  • n ≤ 100 → 冒泡排序取第 K 个,随便写
  • n ≤ 10^5 → 快速排序 O (n log n),能过
  • n ≤ 10^7 → 必须用快速选择 O (n),排序会超时

数据范围告诉你该用什么,而不是你想用什么就用什么。


三、暴力出奇迹?先看看能不能过

3.1 什么时候暴力是正解?

很多人看不起暴力解法,但比赛里能过的暴力就是好解法

尤其是比赛前两道题,数据范围通常很小,暴力直接 AC,省时省力。

判断标准:

  • n ≤ 1000 → O (n^2) 暴力大概率能过
  • 涉及字符串匹配 → 先试试 O (n*m),不行再上 KMP
  • 几何题 → 暴力枚举所有组合,比想复杂算法快得多

3.2 暴力的正确姿势

cpp运行

// ❌ 错误写法:边算边输出,容易超时 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << a[i] + a[j] << endl; } } // ✅ 正确写法:关闭同步 + 批量输出 ios::sync_with_stdio(false); cin.tie(nullptr); // 或者用 printf

C++ 选手记住这两行,能救你无数次 TLE。


四、前缀和与差分:数组题的瑞士军刀

4.1 前缀和:区间求和 O (1)

这是我用得最多的技巧,没有之一。

模板代码:

python运行

def prefix_sum(arr): n = len(arr) pre = [0] * (n + 1) for i in range(n): pre[i + 1] = pre[i] + arr[i] return pre # 求 arr[l...r] 的和(0-based,闭区间) def range_sum(pre, l, r): return pre[r + 1] - pre[l]

适用场景:

  • 多次区间求和查询
  • 子数组和相关问题
  • 配合哈希表找 "和为 K 的子数组"

4.2 差分:区间更新 O (1)

如果题目是 "对数组的某个区间统一加上 val",差分就是你的朋友。

cpp运行

// 差分数组 d,原数组 a // 区间 [l, r] 加 val d[l] += val; d[r + 1] -= val; // 最后求前缀和还原 for (int i = 1; i <= n; i++) { a[i] = a[i - 1] + d[i]; }

经典题型:

  • 航班预订统计
  • 拼车
  • 区间加法

记住:数组题想优化,先想前缀和和差分。


五、双指针:让 O (n^2) 变 O (n) 的魔法

5.1 什么时候用双指针?

满足单调性的问题,双指针基本都能上。

常见类型:

类型典型题目核心思想
快慢指针环形链表、找中点一个走一步,一个走两步
左右指针两数之和、盛最多水两端向中间逼近
滑动窗口最长无重复子串右指针扩展,左指针收缩

5.2 滑动窗口模板(必背!)

python运行

def sliding_window(s): left = 0 window = {} # 窗口内的状态 result = 0 for right in range(len(s)): # 1. 右指针扩展:把 s[right] 加入窗口 char = s[right] window[char] = window.get(char, 0) + 1 # 2. 判断是否需要收缩左指针 while 窗口不满足条件: # 3. 左指针收缩:把 s[left] 移出窗口 left_char = s[left] window[left_char] -= 1 if window[left_char] == 0: del window[left_char] left += 1 # 4. 更新答案 result = max(result, right - left + 1) return result

这个模板能解决 80% 的子串 / 子数组问题:

  • 最长无重复字符子串
  • 最小覆盖子串
  • 长度最小的子数组
  • 找到字符串中所有字母异位词

背下来,比赛直接套。


六、二分查找:不只是 "找数"

6.1 二分的本质:单调性判定

很多人以为二分只能用来 "在有序数组里找某个数",太狭隘了。

二分的本质是:如果一个问题的答案具有单调性(满足条件的是连续一段),就可以用二分来猜答案。

6.2 二分答案模板

python运行

def binary_search_answer(nums, target): left = 最小值 right = 最大值 while left < right: mid = (left + right) // 2 if check(mid): # mid 这个答案行不行? right = mid # 行,试试更小的 else: left = mid + 1 # 不行,得更大 return left

6.3 经典应用

题目:给定一个数组和一个整数 m,将数组分成 m 个非空连续子数组,使得这 m 个子数组各自和的最大值最小。

思路:

  • 猜一个答案 mid(最大子数组和为 mid)
  • 判断:能不能把数组分成不超过 m 段,每段和≤mid
  • 如果能 → 答案≤mid,往小了猜
  • 如果不能 → 答案 > mid,往大了猜

python运行

def splitArray(nums, m): def check(max_sum): count = 1 current = 0 for num in nums: if current + num > max_sum: count += 1 current = num if count > m: return False else: current += num return True left = max(nums) right = sum(nums) while left < right: mid = (left + right) // 2 if check(mid): right = mid else: left = mid + 1 return left

"最大化最小值"、"最小化最大值"—— 看到这种描述,直接二分答案。


七、90% 的人不知道的比赛技巧

7.1 打表找规律

遇到数学题、找规律题,想不出公式怎么办?

暴力打小数据的表,然后肉眼找规律。

举个例子:上楼梯,每次可以走 1 步或 2 步,问 n 阶楼梯有多少种走法?

暴力打表:

n=1 → 1 n=2 → 2 n=3 → 3 n=4 → 5 n=5 → 8

哦!这不就是斐波那契数列吗?公式直接出来了。

比赛里的数学题,十有八九可以打表找规律。

7.2 对拍调试

你的代码过了样例但 WA 了?自己又找不到错?

写一个暴力解法(保证正确但可能超时),写一个随机数据生成器,然后两个程序对拍。

# shell 对拍脚本 while true; do python3 generate.py > test.in # 生成随机数据 python3 brute.py < test.in > out1 # 暴力解法(正确) python3 solve.py < test.in > out2 # 你的解法 if diff out1 out2; then echo "OK" else echo "WA!" cat test.in # 输出出错的数据 break fi done

跑 1000 组数据,bug 无所遁形。

7.3 骗分技巧

实在做不出来?别空着,能骗一分是一分:

  • 特殊值骗分:题目说 n≥1,n=1 时答案是什么?直接特判输出
  • 小规模骗分:n≤20 时暴力,大数据随便输出个值
  • 样例输出:实在不会,把样例输出写上,万一测试用例就是样例呢

比赛排名有时候就差那 5 分、10 分。


八、比赛时间分配策略

8.1 两小时比赛怎么分配?

时间做什么目标
0-10 分钟通读所有题目标记难度,确定做题顺序
10-40 分钟做签到题 + 简单题先把稳拿的分拿到
40-90 分钟攻克中等题核心得分点
90-110 分钟难题骗分 + 检查能拿多少拿多少
最后 10 分钟检查提交别因为低级错误丢分

8.2 关键原则

  1. 先易后难:不要死磕一道题,卡住了先跳
  2. 每道题最多想 20 分钟:想不出来就先放放
  3. 提交前检查:数组开够了吗?long long 了吗?多组数据初始化了吗?

九、推荐刷题路线

最后给大家一个从入门到比赛获奖的刷题路径:

第一阶段(入门):数组、字符串、排序、二分

  • 目标:比赛前两题稳过
  • 题量:约 50 道

第二阶段(进阶):DP、贪心、图论基础、数据结构

  • 目标:中等题能做出来
  • 题量:约 150 道

第三阶段(高阶):高级数据结构、数论、网络流、计算几何

  • 目标:冲击排行榜
  • 题量:300 道 +

刷题平台推荐:LeetCode(基础)、Codeforces(比赛)、洛谷(国内题库)


写在最后

编程比赛这东西,天赋决定上限,努力决定下限。

大多数人还没到拼天赋的程度 —— 把基础算法练熟,模板背好,常见题型一看就有思路,进 Top 10% 真的不难。

最怕的就是:题刷了不少,但从不总结,每次遇到类似的题还是重新想一遍。

收藏这篇文章,比赛前翻一翻,比你刷 10 道水题有用得多。


互动时间:

  • 你最近参加了什么比赛?成绩怎么样?
  • 有什么想看的算法专题?
  • 评论区聊聊,点赞最高的我下期写!

如果这篇文章对你有帮助,点赞👍 + 收藏⭐ + 关注👀三连支持一下,下期更新《动态规划从入门到精通:10 道经典题带你吃透 DP》!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询