骗分技巧,不会做也能拿分
算法竞赛中,骗分是一种生存智慧。蓝桥杯的赛制是OI赛制,只按最终输出判分,不看过程,这给了我们很大的操作空间。一道题你可能只会暴力,甚至完全不会,但只要你能通过部分测试点,就能拿到对应的分数。
这篇总结我在省赛和国赛中常用的骗分技巧,帮助你在考场上最大化得分。
暴力枚举——最朴素的骗分
适用场景
- 题目数据范围很小(比如 n ≤ 10, m ≤ 20)。
核心思想
直接按照题意模拟,哪怕复杂度是 ) 或 ,只要数据小就能过部分点。
示例:全排列枚举
如果一道题需要找“最优顺序”,而 ,直接 itertools.permutations 暴力枚举所有排列,计算每种情况的值,取最优。
import itertoolsn = 8arr = list(range(1, n+1))best = 0for perm in itertools.permutations(arr):# 计算当前排列的得分 score = calc(perm) best = max(best, score)print(best)
优点:代码短,保证正确,能过小数据。注意: 时 6,PyPy 勉强可跑; 时 会超时,但可能仍能过前几个测试点。
打表——本地计算,提交答案
适用场景
核心思想
在本地(或代码开头)用一个循环把所有可能输入的答案算出来,存成字典或列表。提交的代码直接查表输出。
示例:质数判断
如果题目询问 1~1000 中哪些数是质数,你可以在本地先跑一个筛法,把所有质数存下来,然后直接打印。
# 本地运行一次,生成答案列表primes = [i for i in range(2, 1001) if all(i%j!=0for j in range(2,int(i**0.5)+1))]print(primes)
# 提交的代码ans = [2,3,5,7,...]print(ans[int(input())])
进阶:如果输入范围较大但答案有周期性,可以打表找规律。
输出样例——送分点
适用场景
核心思想
直接判断输入是否等于样例输入,若是则输出样例输出。
s = input().strip()if s == "5 3": print("8")else:# 正常代码
注意:只能骗一两个点,但有时一两个点就能让你从 0 分变成 10 分。
特判特殊情况——拿保底分
适用场景
- 题目中有些特殊数据(如 n=0, n=1, 所有值相等)容易处理。
示例:求最大值
如果不会写完整的算法,至少判断一下最小值情况。
if n == 1: print(a[0])returnif all(x == a[0] for x in a): print(a[0])return# 否则正常处理
随机化算法——概率骗分
适用场景
示例:随机化贪心
对于某些排序问题,可以随机打乱顺序多次,取最优。
import randombest = 0for _ in range(10000): random.shuffle(arr) score = calc(arr) best = max(best, score)print(best)
注意:蓝桥杯一般不禁止随机化,但也不能保证100%正确。适合填空题或答案不唯一的情况。
贪心 + 瞎猜——大胆假设
适用场景
- 比如区间调度按右端点排序,背包问题按性价比排序等。
示例:部分背包问题
如果不会动态规划,就按单位价值排序,尽可能多拿价值高的。
items.sort(key=lambda x: x[1]/x[0], reverse=True) # 按性价比降序
即使不是最优,往往也能拿到一半以上的分数。
内置函数与库——偷懒神器
1. 高精度
Python 的 int 无上限,遇到大数运算直接用。
2. 排序与查找
sort, bisect, heapq 等用起来,不要手写。
3. 数学库
math.gcd, pow(a,b,mod) 直接调用。
4. 集合运算
set 的交并补可以快速解决某些计数问题。
5. 字符串内置方法
count, find, replace 等往往比手写快且不出错。
超时优化——PyPy与快读快写
1. 使用 PyPy
蓝桥杯的 Python 环境通常提供 Python 3 和 PyPy3。PyPy 对循环和递归有优化,比 CPython 快 3~5 倍。如果你的代码有大量循环,选择 PyPy 能明显减少超时风险。
2. 快读
import sysdata = sys.stdin.buffer.read().split()it = iter(data)n = int(next(it))
3. 快写
out = '\n'.join(map(str, results))sys.stdout.write(out)
输出最大值/最小值/0/-1——终极骗分
适用场景
- 完全不会做,且题目答案有界(例如求最大值、最小步数)。
- 很多题目的答案不会是负数,或者边界情况就是 0 或 -1。
策略
- 如果题目是求最大值,输出一个大数(如
10**9)。 - 如果题目是判断是否存在,输出
"YES" 或 "NO" 中的一个(根据经验蒙)。
效果:总有一些测试点答案是 0 或 -1,能骗到分。
骗分综合实战
题目:给定一个无向图,求从 s 到 t 的最短路径长度,如果不可达输出 -1。你的水平:只会 DFS 暴力搜索,但图很大,担心超时。
骗分策略:
- BFS 限制深度:设置最大搜索深度为 100,如果找到就输出,否则输出 -1(可能蒙对)。
- 输出 -1:如果前面的都没跑出来,直接输出 -1。
代码片段:
defbfs_limited():if s == t:return0# 最多搜索 5 层from collections import deque q = deque([(s, 0)]) visited = set([s])for _ in range(5): # 只搜5层for __ in range(len(q)): u, d = q.popleft()for v in graph[u]:if v == t:return d+1if v notin visited: visited.add(v) q.append((v, d+1))return-1print(bfs_limited())
这样至少能通过那些距离很近的测试点。
骗分注意事项
- 不要滥用:骗分是在正解写不出来或时间不够时的补充,不能替代学习。
- 结合数据范围:观察题目给的“对于 30% 的数据,n ≤ 10”,这类点暴力就能过。
- 保持代码整洁:骗分代码也要结构清晰,方便后期改进。
- 蓝桥杯是 OI 赛制:没有罚时,所以你可以先提交一个骗分版本,然后慢慢优化,覆盖更多点。
骗分策略总结表
最后的话:骗分不是丢人的事,而是合理利用规则。在省赛中,一道 20 分的题你通过骗分拿到 5 分,可能就决定了你是否进国赛。但请记住,实力才是根本,骗分只是雪中送炭。