资讯动态

OJ刷题参考代码的正确打开方式:从抄到改,从AC到理解

发布时间:2026/10/24 18:17:45 来源:尧图企业网站定制
简介这份资源收录了杭州电子科技大学在线OJ平台1000至1099号题目的C/C解题代码共90个文件以cpp源文件为主另有少量c文件及配套工程文件压缩包大小1.1MB适合正在刷题备考或想提升算法能力的编程学习者。题目覆盖基础算法、数据结构、数学应用、逻辑推理等常见类型例如大数运算、动态规划、图论搜索等。代码均经过调试可直接运行对照学习。通过学习这些实现可以理解不同题目的解题思路与性能优化技巧并熟悉C/C的工程组织方式。目前已有1839人学习下载是一份经过验证的OJ刷题参考资料。1. 先弄清这批 1000-1099 参考代码能干什么、不能干什么刷题的人应该都经历过这种场景在某校OJ上从第1000题开始刷AB好不容易过了到下一题突然卡住看着题目怀疑自己是不是没学过C语言。这时候一份覆盖1000到1099题的参考代码合集就很有价值——它不是让你无脑抄完然后假装会了而是让你在卡壳时看一眼“AC的人是怎么处理输入输出、怎么判断边界条件的”对着代码定位自己的问题在哪。这份资源是某校OJ前100道题的代码集合覆盖简单数学、字符串处理、模拟这些入门必考题型适合刚开始刷OJ的学生、准备机考的从业者以及想给后来者留一份入门资料的学长。但别指望它帮你包办一切代码有对有错有的藏着旧编译器的怪癖怎么挑、怎么改正是后面几章的重点。2. 这批代码到底是什么题型分布、文件结构与选码标准2.1 1000-1099在OJ刷题路线里的位置某校OJ的1000-1099这100道题本质上是一条精心设计的入门路线。1000题通常是经典的AB考察最基本的输入输出1001到1005开始引入多组输入、循环控制1006到1015左右出现素数、最大公约数、进制转换这类数学题再往后是字符串处理比如统计字母、反转字符串到1080之后开始有简单的模拟题比如日期计算、矩阵操作。这个梯度不是随意排的每个范围都对应一类编程能力。这份代码合集的价值不在于“答案”而在于它暴露了这批题的常见写法。比如1000题十个有九个半用while(scanf(%d%d, a, b) ! EOF)但新手往往会先写一个scanf然后直接输出遇到多组输入就懵。参考代码里这种“套路写法”恰恰是入门最该学的。2.2 拿到代码后先做四步体检代码合集不是拿来就能用的我一般会先对每份代码做四个检查淘汰掉不值得看的第一看头文件。如果一份代码只写了bits/stdc.h在较老的编译器上直接编不过这类代码要么你本地升级编译器要么把它替换成具体的标准头文件。第二看输入输出格式。题目要求“每个结果占一行”代码里是不是真的每轮循环都输出换行少一个换行直接Presentation Error。第三看边界条件。比如求阶乘的题目n0时输出1很多参考代码会在这种地方偷懒。第四看变量名。全是a、b、c的代码就算能过学习价值也有限因为它没法教你怎么组织逻辑。这四个检查点对应四个不同的翻车场景筛完剩下的代码才值得往下走。2.3 我的归档习惯按题号、语言、备注三层组织代码合集往往是一个文件夹几十个文件直接翻会崩溃。我拿到这类资源的第一件事是重新组织目录结构大致是这样mkdir -p oj_1000-1099/{c,cpp,python} for f in oj_1000-1099/*.c; do mv $f oj_1000-1099/c/; done for f in oj_1000-1099/*.cpp; do mv $f oj_1000-1099/cpp/; done这段脚本把原始文件夹里的C文件和C文件分别挪到c和cpp子目录。如果合集里有Python代码也能用同样方式归到python目录。归档这一步看似浪费时间但后面找代码、批量编译、写对拍脚本都依赖一个干净的目录结构。归档的同时我会顺手在文件名末尾加上简短备注比如1000_main_template.c、1011_prime_sieve.c搜索时一眼能看出这题考什么。提示归档时保留原始文件名中的题号前缀别自己重新命名否则后面跟OJ题目对照时很难对应。3. 把参考代码跑通并改成自己的环境、对拍与提交3.1 本地编译环境怎么搭在Windows上最简单的方式是装一个带GCC的工具链Linux和macOS用系统自带的gcc就能编译。我自己的习惯是全部在命令行下操作手动编译能清楚看到编译告警IDE里那些黄色波浪线反而容易忽略。gcc -stdc11 -Wall -Wextra -O2 -o 1000 1000.c拆开说-stdc11指定C语言标准避免某些老代码依赖C99的模糊特性-Wall和-Wextra打开所有常见告警比如变量未使用、比较类型不匹配这些告警在线判题系统不会告诉你但往往是WA的前兆-O2是优化开关OJ评测一般也开O2本地和线上环境对齐能少踩很多坑。编译如果没有报错再跑一下题目给的样例输入echo 1 2 | ./1000如果输出3说明这份代码至少能过样例。注意我说的是“至少”样例覆盖永远不够这也是对拍脚本存在的意义。3.2 用对拍脚本验证正确性参考代码最大的风险是它只过了当时的评测数据但边界和反例可能一碰就碎。写一个简单的对拍脚本用随机数据拿两份代码对比输出能把这个问题压到最低。import random import subprocess import sys # 随机生成AB数据写入input.txt for _ in range(100): a random.randint(0, 10000) b random.randint(0, 10000) with open(input.txt, w) as f: f.write(f{a} {b}\n) # 分别运行参考程序和自己的程序 out1 subprocess.run([./ref], stdinopen(input.txt), capture_outputTrue, textTrue) out2 subprocess.run([./mine], stdinopen(input.txt), capture_outputTrue, textTrue) if out1.stdout.strip() ! out2.stdout.strip(): print(fdiff at {a} {b}: ref{out1.stdout.strip()} mine{out2.stdout.strip()}) sys.exit(1) print(all ok)这段代码把随机生成的测试数据喂给两个程序逐条对比输出。参数上random.randint(0, 10000)可以按题目数据范围调整跑100轮循环对入门题足够如果测复杂模拟题建议加到1000轮。对拍脚本的意义在于它能一次性找出代码里隐藏的整数溢出、格式化输出错误、数组越界这类问题。3.3 从“抄代码”到“写代码”的改写流程参考代码直接提交确实能过但那就失去了刷题的意义。我建议的流程是三步第一步读代码把注释和空行全部删掉默写一遍第二步把变量名全部替换成有意义的词比如把x改成num_count第三步给核心逻辑加注释自己解释为什么这一步要这么写。这个过程走完代码才算变成你的。// 以1000为例默写后强化边界处理 #include stdio.h int main(void) { int a, b; while (scanf(%d%d, a, b) 2) { printf(%d\n, a b); } return 0; }这里的scanf返回值是成功匹配的参数个数写成 2比写! EOF更严谨。很多参考代码写的是while(scanf(%d%d, a, b) ! EOF)这个写法在遇到格式错误的输入时会出问题。输入只有两个整数时两者等价但养成检查返回值的习惯后面处理多行混合输入时会少踩很多坑。4. 避坑1000-1099参考代码里最常见的五个坑4.1 本地编译通过OJ上报Compile Error现象代码在自己电脑上gcc编译没有任何问题交到OJ上报编译错误。原因参考代码里用了bits/stdc.h这种非标准头文件或者用了C11之后才有的语法特性而OJ用的编译器版本比较老。本地环境是GCC 12OJ可能还在用GCC 5标准支持完全不同。解决把bits/stdc.h换成具体的头文件比如stdio.h、string.h、stdlib.h。如果是C代码把algorithm、vector按需引入。提交前先查OJ支持的语言标准一般在线OJ的FAQ里都有说明。4.2 本地跑样例全对OJ上全WA现象题目给的示例输入输出本地运行全对提交上去一个都不过。原因最常见的是多组输入处理写错了。有些题目没说明会有多组输入但评测数据就是多组的。参考代码用while(scanf(...) ! EOF)循环处理你自己写的时候只写了单次读取。解决先把所有输入相关代码找出来确认是否在循环里。拿1000这类最基础的题验证如果题目没明确说“只有一组输入”默认就要按EOF循环处理。4.3 用了cin/cout提交显示超时现象用C的cin、cout写逻辑本地秒出结果OJ上显示Time Limit Exceeded。原因C的iostream默认要和C的stdio同步这导致cin每次读取都会有额外开销。入门题的评测数据量不大但有些题目的输入输出量巨大同步开销直接拖垮程序。解决在main开头加上ios::sync_with_stdio(false);和cin.tie(0);或者干脆用scanf/printf混写。注意关掉同步之后不能再用printf输出否则顺序会乱。我一般建议C选手统一用cin/cout并关同步避免混用。4.4 素数题数组越界本地没报错现象求区间内素数的题目本地测试小数据没问题OJ上跑大数据直接Runtime Error或者答案错。原因最常见的是数组开的大小不够。比如筛法求素数题目给的范围是1000000代码只开了1000的数组越界访问在本地可能没暴露因为栈内存刚好够用但OJ上直接就崩了。解决先看题目数据范围数组大小要比最大范围至少大1。写筛法相关的题我习惯用#define MAXN 1000005这种宏把上限固定并且在循环里加上边界判断。遇到越界错误优先排查所有数组下标。4.5 参考代码来自旧版本存在过时写法现象一份代码在OJ上能AC但里面用了gets()这类函数本地编译直接警告甚至报错。原因gets()因为不安全在C11标准中已经被移除。网络流传的OJ代码里这种过时写法随处可见直接复制的后果就是编译不过。解决把gets()换成fgets()并手动去掉末尾换行符。改成这样char buf[128]; if (fgets(buf, sizeof(buf), stdin) ! NULL) { buf[strcspn(buf, \n)] \0; }这段代码先用fgets读取一行limit是sizeof(buf)防止缓冲区溢出然后用strcspn找到第一个换行符的位置并替换成字符串结束符。对比原版gets()多写两行但安全性和可移植性都上来了。5. 进阶用法把1000-1099按专题重组形成自己的刷题索引拿到这份代码合集最高的利用率不是逐题刷完而是按专题重组。我自己做过一件事把这100道题的代码全部按数学、字符串、模拟、数据结构四类重新归档每类建一个索引文件标注题号、核心思路、当时踩的坑。操作很简单以当前目录为例mkdir -p topics/{math,string,simulate} cp 1002.c 1006.c 1021.c topics/math/ cp 1008.c 1013.c 1030.c topics/string/归档之后你会突然发现同一类题目的解法高度相似。比如这批题里所有素数相关的题核心都是那一个筛法所有字符串统计题核心都是循环遍历加计数。把这些共性抽出来你就得到了属于自己的“解题模板库”以后再遇到类似题目就不是从零开始而是先想“这题对应我模板库里的哪个模式”。第二个进阶用法是复杂度复盘。每道题AC之后回来看参考代码的时间复杂度和空间复杂度确认代码是不是最优解。举个例子求n以内素数个数有人写两层循环O(n^2)也能过入门题但参考代码用埃氏筛O(n log log n)差距在数据变大后立刻显现。我会在索引文件里每个题后面加一列复杂度记录等再刷到后面区间时看到“素数筛——埃氏筛——O(n log log n)”就能快速回忆起思路。从那以后我每次拿到一份OJ代码资源第一件事都是先跑一遍编译告警再写一个对拍脚本做随机验证最后按专题归档。这套流程看起来多花了半小时但省下的是打开题目发现代码根本不能用、或者在OJ上连续WA四五次的几小时。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑