OJ基础题题解使用指南:从输入输出到算法入门
发布时间:2026/10/31 5:08:44 锦皓数字建站

简介这份资料面向准备北京大学POJ在线评测与ACM算法训练的学习者收录一批基础题目的C实现答案适合刚接触算法竞赛、需要对照思路巩固语法与常见算法的读者。压缩包共157个文件其中156个为cpp源码另有1个txt说明文件整体约59KB体积轻便便于按题号整理和本地编译运行。资源已有2653人学习下载说明其在入门刷题场景中具有一定参考价值。读者可借助这些代码查看输入输出处理、循环与数组、模拟、简单数论、动态规划及搜索等题型的实现方式并对照OJ判题结果排查边界条件与格式错误由于以源码为主更适合作为个人练习后的参考与思路比对而非直接提交。1. 先搞懂一个概念在线评测题库和“题解”到底是什么很多人第一次打开这类资源反应都差不多一叠按编号命名的源文件点开全是代码读三行就关掉了。这很正常——它更像习题册背后的答案页而答案本身不会告诉你题目在问什么。所以先把概念说清楚有一类网站叫在线评测题库上面挂着大量编程题你在本地写好程序提交上去服务器拿预设的测试数据跑一遍对就通过错就告诉你是哪一类错。这份资源就是其中一部分基础题目的参考答案集合语言以 C/C 为主难度集中在上手阶段。它适合刚学完一门语言的语法、想找题练手、又不知道从哪道题开始的新手属于那种“照着敲一遍就有收获”的入门材料。2. 为什么零基础也要从基础题开始把语法变成手感学编程最容易卡住的地方通常出现在“我刚看完语法书接下来该干嘛”这一步。变量、循环、条件判断书上都懂合上书想写个小程序手指头就停在键盘上方不动了。刷基础题正好填上这个缝它给你一个具体到不能再具体的小任务你只要把这个任务翻译成代码然后交给一台不知疲倦的机器去判断对错。2.1 语法书看十遍不如让判题机给你一次通过看书是输入写代码是输出中间隔着一道很难自己跨过去的坎。你在书里看到for循环觉得自己完全理解了可题目要求“读入 n 个数求和后输出”你可能立刻卡在三个地方n 怎么读、数存哪儿、循环从 0 开始还是从 1 开始。这些细节书里通常一句话带过只有自己写才会暴露。判题机的好处是它不会照顾你的情绪。你的程序对就是对错就是错而且会告诉你错在哪一类。这种即时、客观、不讲人情的反馈是新手阶段最稀缺的东西。我见过太多人学了半年语法写不出一段完整的、能跑通输入输出的程序问题不在智力而在于从来没被“判”过。所以别把刷基础题当成考试把它当成练手感。就像学游泳岸上把动作要领背得再熟下水那一下还是得自己扑腾。第一道题通过时那声“通过”比看十页教程都提神。2.2 一份现成的答案集省下的是“卡壳时间”新手做题卡壳其实分三种情况得分开对待。第一种是完全没思路看完题面不知道从哪下手。这种在基础题里不算多因为基础题的题意通常很直白。第二种是有思路但写不出来知道要循环、要判断就是不知道怎么组织成代码。第三种是写出来了但过不了本地跑着自己造的样例没问题提交上去被判错。第二种和第三种一份可运行的参考答案能帮上大忙——它把“想法”和“能跑的代码”之间那段空白填上了你能直接看到别人是怎么组织循环、怎么定义变量、怎么处理输入的。但这里有一条血泪经验答案不是用来抄的是用来对照的。抄一遍交上去通过第二天换一道同类型的题你还是不会。因为抄的过程里你只是搬运字符脑子里没有发生“翻译”这件事。正确的用法后面第 4 章会细讲这里先记住一句话先自己撞墙再看答案看完还要默写一遍。2.3 基础题到底在练什么其实是三件事很多人以为基础题就是练语法其实不是。语法只是入场券真正反复练的是三件事。第一件是输入输出的处理。这是新手翻车最集中的地方题目到底给一组数据还是多组多组的话什么时候停输出要不要换行末尾要不要多一个空格这些问题在真实项目里也天天遇到只是形式不同。基础题把它们压缩成最小模型逼你养成“先看清输入输出格式再动手”的习惯。第二件是基本数据结构的用法。数组怎么开、开多大、下标从几开始字符串怎么读、怎么比较结构体怎么把几个相关的值打包在一起。这些东西单独讲很枯燥放到题目里就有了意义。比如一道“统计每个数字出现几次”的题你自然就理解了“数组可以当计数器用”这件事比背定义有效得多。第三件也是最容易被忽略的一件把一段自然语言描述翻译成一步步可执行操作的能力。题面说“把序列里相邻的相同元素合并”你得先想清楚这是要遍历、要比较、要记录上一个值然后才是写代码。这个“拆解”的动作才是编程真正的核心技能而它只能靠大量的小题目喂出来。2.4 这份资源能解决什么不能解决什么说清楚边界用起来才不别扭。它能给你的一批基础题的参考实现可以直接编译运行的完整代码常见的输入输出写法套路比如多组数据读到文件结尾怎么写、给了组数怎么写一些边界情况的处理方式比如 n 等于 0 时怎么办。对刚上手的人来说这些就是“看得见的台阶”。它不能给你的不能代替你思考代码放在那儿不会自动变成你的能力不覆盖高难度题目基础题和算法竞赛题之间还有很长一段路也不保证是写法最优、风格最好的版本参考实现的意义在于“能跑通、思路清楚”而不是“教科书级范例”。提示把这份资源当成“答案册”而不是“教材”。教材告诉你该学什么答案册只在你做完题之后告诉你差在哪。顺序反了效果会差很多。3. 第一个例子怎么跑从读题到提交的完整流程理论说完了接下来动手。这一章的目标很单纯让你在半小时内把第一段代码提交上去并且看到那个让人心情变好的结果。整个过程分四步——准备工具、读题、写代码、本地自测最后才是提交。3.1 先把工具准备好一个能编译能运行的最小环境不需要复杂的开发环境两样东西就够一个顺手的代码编辑器用来写文件一个命令行里的编译器用来把代码变成能跑的程序。Windows 上通常装一个带编译器的集成环境或者单独装编译器再把它的路径加进系统环境变量macOS 和 Linux 一般自带编译器打开终端就能用。装完之后在命令行里敲一句确认g --version如果屏幕上打印出编译器的版本信息说明能用了。如果提示“找不到命令”那就是路径没配好回头检查安装步骤别在这一步硬扛——这是新手第一个容易放弃的地方其实只是环境变量没生效。接下来建一个自己的文件夹比如叫oj以后每道题在里面建一个源文件命名随便a.cpp、sum.cpp都行。养成“一道题一个文件”的习惯比全部堆在一个文件里改来改去清楚得多。注意不要用中文路径也不要在文件名里加空格。某些环境下这类路径会让编译命令莫名其妙地失败排查起来非常费劲。3.2 读题的三个固定动作输入、输出、边界读题不是“看一遍”而是有固定套路地看三遍。养成这个习惯能省掉后面一大半的调试时间。第一遍看输入给几组数据第一行有没有一个数字表示组数每组数据有几个值值的范围多大需不需要用更大的整数类型有没有明确说“输入以文件结束为终止”第二遍看输出每组结果单独一行还是用空格隔开末尾有没有多余空行大小写有要求吗保留几位小数第三遍看边界n 最小可能是多少会不会是 0会不会有负数最大值多大会不会超出普通整数范围举个最常见的例子。题面写“输入两个整数输出它们的和”看起来一句话说完但实际数据是好几组、一直给到文件结束。很多新手按“只读一组”写完提交被判错然后盯着代码看半小时也看不出问题——因为代码没错是他把输入模式看漏了。3.3 第一个能过的程序两数相加的多组写法假设题目就是“多组数据每组两个整数输出和每组一行”。参考实现长这样#include cstdio int main() { int a, b; // scanf 返回成功读入的变量个数读到文件结尾时会小于 2循环自然结束 while (scanf(%d %d, a, b) 2) { printf(%d\n, a b); // 每组结果单独一行行末的换行不能省 } return 0; }逐行说清楚。第一行把标准输入输出库引进来scanf和printf都在里面。int a, b;定义两个整型变量用来装这一组数据。关键是while那一行scanf本身有返回值它返回“成功读到了几个值”这里要读两个值所以写 2。当输入数据读完scanf读不到东西返回值变成小于 2 的数条件不成立循环结束。这就是“读到文件结尾为止”的标准写法。printf(%d\n, a b);里的%d是整数的占位符\n是换行。别小看这个\n它决定了你的输出是不是“每组一行”漏掉就是格式错误。如果题目的输入模式换成“第一行给一个数字 T表示有 T 组数据”写法就变了#include cstdio int main() { int t; scanf(%d, t); // 先读入组数 while (t--) { // 循环 t 次t-- 是先用再减 int a, b; scanf(%d %d, a, b); printf(%d\n, a b); } return 0; }while (t--)这个写法新手常看不懂拆开就是判断 t 是不是非零是就进循环体同时把 t 减 1。t 从 5 开始循环体执行 5 次。两种输入模式的差别是新手第一个大坑——代码结构完全不同判题结果却都是“答案错误”光看错误提示根本猜不到原因。3.4 本地自测先过自己造的样例再交给判题机写完了别急着提交。先在本地造一组输入把程序跑一遍看看输出对不对。建一个文本文件in.txt写两行1 2 3 4然后在命令行里编译并运行g -O2 -Wall -o sum sum.cpp ./sum in.txt第一行是编译。-O2打开优化程序跑得更快很多题目的时间限制靠它才过得去-Wall打开常用警告它会提醒你“变量没初始化”“类型转换可能丢精度”这类问题非常值得开。-o sum指定输出的程序名叫sum。第二行是运行 in.txt表示把文件内容当作程序的输入喂进去。如果屏幕上出现3和7两行说明逻辑对了。接下来再补两组边界测试输入0 0看输出是不是0输入一个很大的数看会不会溢出。这些额外样例不需要提交纯粹是给你自己排雷。3.5 提交之后那张判题结果到底在说什么把代码贴进提交框等几秒屏幕上会返回一个结果。新手第一次看基本是懵的先记住这张对照表判题结果它想告诉你什么第一件事去查什么通过所有测试数据都过了可以去看别人的写法比较风格差异答案错误程序跑完了但某些数据的结果不对输入模式、边界值、整数范围格式错误结果大概率是对的输出格式不对行末换行、多余空格、空行超时结果可能对但跑得太慢有没有多余的循环读入方式是否太慢运行错误程序中途崩了数组越界、除以零、递归太深编译错误代码根本没编译成功看编译器给的行号和报错信息最值得说的是“格式错误”和“答案错误”的区别。前者说明你思路对了只是排版没对上改一个换行符可能就过了后者才是逻辑问题。很多人看到不是“通过”就慌了其实这两种情况的排查方向完全相反。看懂这张表你就有了排查的起点而不是对着一屏代码干瞪眼。4. 把一份题解集用出价值对照、复盘、二次默写拿到答案集最常见的错误用法是“不会就翻翻到就抄抄完就下一题”。这样刷二十道水平和不刷差不多。真正有效的用法有一套固定流程虽然慢一点但每一步都在往你脑子里装东西。4.1 十五分钟原则先自己撞墙再看答案给自己定一条硬规矩一道题先独立想十五分钟。这十五分钟里可以翻笔记、可以查语法、可以在纸上画就是不许打开答案。为什么是十五分钟太短了你还没把题目在脑子里过一遍太长了新手容易陷进去出不来一小时耗在一道基础题上性价比太低。十五分钟是个折中点足够你尝试一两种思路并且失败一次。十五分钟之后还写不出来就去看答案。这时候看和一开始就看效果完全不同——你脑子里已经有了一堆“为什么这样不行”的疑问答案的每一行都在回答这些疑问信息吸收率会高很多。我第一次按这个规矩做题时前几道全是十五分钟就投降。但做到第十道左右我发现自己在看答案之前已经能猜到大概思路了那种感觉很实在。4.2 看懂一份答案要问自己四个问题答案摆在面前别急着抄。先回答四个问题答不上来就说明还没看懂。第一个问题这道题到底在考什么是考输入输出的处理还是考数组的用法还是考某个简单的模拟过程想清楚这一点你才知道该记住什么。第二个问题关键变量是哪几个一份能跑的代码里总有一两个变量承担了核心作用比如计数器、当前最大值、上一个读到的值。找到它们再看它们在哪里被修改。第三个问题边界是怎么处理的特别注意那些看起来“多余”的判断比如if (n 0)、循环写成i n - 1。这些地方往往就是新手会漏掉、导致被判错的关键点。第四个问题如果让我自己写我会在哪一步卡住把这一步单独拎出来那是你这道题真正的收获。四个问题答完你才算“读”过这份答案而不只是“看”过。4.3 二次默写把“看懂”变成“会写”合上答案新建一个空文件从零把这道题再写一遍。不许复制粘贴不许偷偷瞄。这个过程会很挫败因为你会发现刚才明明看懂了写的时候还是卡在scanf的返回值上、卡在循环的边界上。但正是这些卡住的地方才是你真正没掌握的地方。写完之后编译、跑样例、和答案对比找出差异再写第三遍。一般来说同一道题默写两到三遍基本就长在脑子里了。之后再遇到同类型的题你会发现自己不用想就能写出输入输出的框架注意力可以全部放到逻辑上——这就是所谓的手感。提示默写的时候刻意把变量名改成自己的习惯写法不要照搬答案里的名字。改名字这个动作会强迫你理解每一行在干什么抄名字则不会。4.4 建一个自己的错题本不用很正式一个文本文件就行。每道做错或者卡住的题记三样东西题目编号加一句话题意方便以后回看时快速回忆我错在哪写具体比如“把多组数据写成了只读一组”“数组开小了”正确做法的关键一步一句话比如“先读组数 T 再循环”。积累到二三十条之后你会发现错误在重复。翻一翻错题本看看哪类错误出现了三次以上那就是你下阶段要重点练的方向。这比漫无目的地刷题高效得多也是我认为新手最值得养成的一个习惯。5. 新手最容易踩的五个坑现象、原因和解决办法这一章讲的全是我见过、也自己踩过的坑。按“现象 → 原因 → 解决”排遇到时对着查比自己瞎猜快得多。5.1 坑一本机跑得好好的提交就是答案错误现象自己造了几组样例输出全都对提交上去却反复被判答案错误改来改去也没用。原因最可能是把输入模式看漏了。你手上造的样例只有一组数据而题目的真实数据是多组你的程序只处理了第一组就结束了。第二种可能是数据范围超出了int题目给的数到十亿级别两个一加就溢出了。第三种可能是题目有隐藏的边界比如 n 可以是 0、可以有负数。解决先回到题面逐字确认输入格式尤其注意“多组”“以文件结束为终止”“第一行是组数”这类描述。然后把整数换成范围更大的类型试试把边界值 0、1、最大值都造一遍跑跑看。养成提交前先造三组样例的习惯其中至少一组是边界。5.2 坑二结果明明对却被判格式错误现象判题结果不是答案错误而是格式错误。你自己看输出数字都对怎么看都不像有问题。原因输出格式的细节没对上。常见的有三种每组结果后面漏了换行全部挤在一行多组数据之间多打了空行行末多了一个空格。这些在屏幕上肉眼几乎看不出来但判题程序是逐字符比对的差一个空格就是错。解决把题目的输出说明再读一遍确认是“每组一行”还是“空格分隔”。如果实在看不出来试试在每组输出后统一加换行或者去掉末尾多余的空格。有时候改一个\n就过了别怀疑人生这是最常见的翻车方式之一。5.3 坑三多组数据只处理了第一组现象程序能跑第一组数据的答案是对的后面的全错或者干脆只输出了一行。原因输入循环写错了。要么根本没有循环只读了一次要么循环条件写成了while (1)却没有退出条件程序卡死要么把“先读组数 T”和“读到文件结束”两种模式搞混了用错了框架。解决先看题面属于哪种模式。给了组数 T 的用先读 T 再循环 T 次的写法没给组数、只说多组数据的用scanf返回值判断。两种框架别混用这是两道完全不同的模板写之前先确定用哪个。写完拿两组数据测一下如果只输出一行基本就是这个问题。5.4 坑四数组开小了程序跑着跑着就崩了现象本地小数据测试完全正常提交大数据就报运行错误或者自己测试时程序突然退出、输出一堆乱码。原因数组开小了或者下标越界。题面说 n 最大到一万你开了 1000 的数组数据一大就越界写入覆盖掉别的内存。还有一种情况是循环写成i n而数组只有 n 个元素多访问了一位。解决把数组开得比题目给的最大值大一点比如最大一万就开一万零五留点余量多开几个元素不占多少内存但能省掉很多玄学问题。循环边界统一用而不是除非你非常确定要多算一位。写完顺手检查一遍每个数组的声明和每个循环的上界。5.5 坑五答案抄过去了换道题还是不会现象答案集里的题照着敲都能通过正确率看着挺高。可一关掉答案换道同类型的新题还是不知道从哪下手。原因抄写这个动作只动手指不动脑子。你没有经历“从题面到思路”的翻译过程也没有经历“从思路到代码”的搭建过程跳过了最难也最有价值的两个环节。解决回到第 4 章那套流程——十五分钟原则、四个问题、二次默写。慢是慢但每道题都会留下东西。宁可一周只做五道题并全部默写通过也不要一天抄二十道。这个道理听起来像老生常谈但真正做到的人不多做到了的人进步速度差别非常明显。6. 下一步学什么从基础题到算法入门的路线把基础题刷顺之后很多人会陷入第二个迷茫期题会做了但不知道下一步往哪走。这里给一条我自己走过的路线按顺序来不用跳。第一阶段把“输入输出 数组 字符串”这三样练到不用想。目标是看到题面就能立刻判断输入模式、立刻确定数据用什么存。这个阶段大概需要二三十道题重点不是难度是熟练度。第二阶段进入排序和查找。手写一遍冒泡或选择排序再用语言自带的排序函数写一遍比较两者的差别然后练二分查找理解“有序”这个前提为什么重要。这个阶段开始有“算法”的味道了。第三阶段接触贪心和简单的模拟题。贪心的核心是“每一步都选当前看起来最好的”题目通常不难想难在证明入门阶段不用纠结证明先把能过的写出来。第四阶段递归与简单的搜索。从求阶乘、斐波那契入手再过渡到“走迷宫”这类需要回溯的题。这个阶段会第一次真正体会到“函数调用自己”是怎么回事。第五阶段最基础的动态规划。从数字三角形、最长上升子序列这类经典入门题开始理解“把大问题拆成小问题并记录结果”这个思路。阶段主要练什么大致题目量判断自己过关的标准一输入输出、数组、字符串2030 道看题就能定输入模式不用试错二排序、二分查找1520 道能说清每种排序的差别和适用场景三贪心、模拟1520 道能把题面步骤一条条翻译成代码四递归、简单搜索1520 道能画出递归的展开过程五基础动态规划1015 道能自己写出状态和转移式再说一个具体技巧每进入一个新阶段先找两道最简单的题“探路”把这一类的代码框架默写熟再往上加难度。别一上来就挑标着高难度的题那只会让你怀疑自己不适合学编程而问题其实出在选题上。最后说说我自己的教训。刚开始刷题那阵我特别爱看答案看完觉得“哦原来是这样”然后心安理得地下一题。一个月下来做了六十多道实际掌握的可能不到十道。后来改成每道题必须默写一遍才算过关进度一下慢到一周五道但两个月后再回头做以前的题基本都能独立写出来。从那以后我每次做题都强制走一遍“先想十五分钟、再看答案、合上默写”的流程再也没跳过。慢一点真的没关系怕的是原地转圈还以为自己在前进。这份基础题答案集就当是你练手时的参考答案册别供着也别抄。挑一道最简单的打开编辑器敲下第一行#include跑通它你会明白那种感觉。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。