
简介这份资料面向南京信息工程大学计算机相关专业学生及算法初学者整理了2021年LEVOJ在线编程平台部分题目的参考答案与解析帮助读者在刷题过程中对照思路、查漏补缺。内容覆盖字符串处理、数组与动态规划、图论最短路径与最小生成树、数论与数学逻辑等方向并涉及排序、二分查找、栈与队列、递归回溯等基础算法与数据结构适合作为课程实验与竞赛训练的辅助材料。资源以zip压缩包形式提供包内共0个文件整体约12KB体量轻便便于快速取用。目前已有3136人学习下载说明其在南信大校内及编程练习群体中具有一定参考价值。读者可借助其中的解题思路梳理算法选择依据理解状态转移、图结构建模与数学转化等关键环节并对照代码实现优化自身方案逐步培养将实际问题抽象为计算模型的能力。1. 南信大 levoj 参考答案从“能跑”到“能讲清楚”的那道坎如果你在南信大 levoj 上刷过题大概率经历过这个场景题目描述读了三遍样例过了提交却 WA 得莫名其妙或者干脆连思路都没有搜到一份“参考答案”复制粘贴过了但下次遇到同类题还是不会。这份 2021 南信大 levoj 部分参考答案真正有价值的不是代码本身而是它背后那套“从题目到 AC”的拆解逻辑。levoj 作为校内 OJ题目风格偏基础但坑点密集很多题表面考语法实际考的是边界处理和输入输出格式。适合谁看刚接触 OJ 刷题、被 levoj 卡住、想搞懂“为什么这样写能过”的在校生以及想带学生刷题的助教。这篇不堆代码而是把每道题从读题、选型、实现到排错的全过程摊开讲让你下次遇到类似题能自己推出来。2. levoj 题目分类与读题方法先判断它到底在考什么2.1 从题目描述里提取三个关键信息levoj 的题目描述通常不长但信息密度高。我一般会先圈出三样东西输入规模、输出格式、边界条件。输入规模决定你选什么算法——n 小于 1000 可以暴力n 到 10^5 就得考虑 O(n log n)。输出格式最容易被忽略levoj 很多题对空格、换行、末尾是否有空行极其敏感多一个空格就是 Presentation Error。边界条件包括 n0、n1、空输入、最大值、负数这些先列出来写完代码逐个测。举个例子一道“求 n 个数的和”的题描述里写“多组输入每组第一行是 n接下来一行 n 个数”。这里的关键信息是“多组输入”意味着你要用 while(cin n) 或 while(scanf(%d, n) ! EOF) 这种循环读取方式而不是只处理一组。很多新手翻车就翻在这里样例只给一组本地跑过了提交上去只过第一个测试点。提示levoj 的测试数据通常包含多组样例往往只展示一组别被样例骗了。2.2 按题型建立自己的分类索引刷 levoj 不要一题一题孤立地刷按题型归类效率高得多。我习惯分成这几类输入输出格式题、模拟题、简单数学题、字符串处理、数组与排序、递归与分治、简单动态规划。每类题有固定的“起手式”。比如输入输出格式题核心就是处理多组数据和格式控制模拟题的核心是把题目描述翻译成一步步的操作别急着优化字符串处理题要熟悉 getline、cin.get、stringstream 的用法和区别。建立索引的好处是下次遇到新题先判断它属于哪一类然后直接套用那一类的模板和注意事项。比如看到“多组输入 每组输出一个结果”立刻想到用 while 循环包住整个处理逻辑并在每组输出后换行。看到“字符串包含空格”立刻想到用 getline 而不是 cin 。这种条件反射能帮你省下大量试错时间。2.3 用“手算样例”验证理解是否正确读题之后别急着写代码先拿样例在纸上手算一遍。手算的过程能暴露你对题目的理解偏差。比如一道排序题样例输入是 5 3 1 4 2输出是 1 2 3 4 5你手算一遍发现就是升序排列那没问题。但如果输出是 5 4 3 2 1你就得想是不是降序或者题目有别的规则。手算还能帮你发现边界情况比如样例里有没有重复元素、有没有 0、有没有负数。手算之后再想一个样例之外的测试用例自己算一遍预期输出写代码时用这个用例来验证。这个习惯能让你在提交前就发现大部分逻辑错误而不是等 WA 了再回头找。3. 从零写出一道 levoj 题的完整流程以“多组数据求和”为例3.1 题目拆解与伪代码设计假设题目是多组输入每组第一行一个整数 n第二行 n 个整数求这 n 个数的和每组输出一行。先拆解多组输入 → 外层循环每组读 n → 读一个整数读 n 个数 → 内层循环求和 → 累加变量输出 → 每组一行。伪代码写出来while (还有输入) { 读入 n sum 0 for i 1 to n: 读入 x sum sum x 输出 sum 并换行 }伪代码的好处是让你先关注逻辑不被语法细节干扰。写完伪代码再翻译成 C 或 Python。3.2 C 实现与关键参数说明#include iostream using namespace std; int main() { int n; // while(cin n) 是处理多组输入的惯用法 // cin n 在遇到 EOF 或输入错误时返回 false循环自动结束 while (cin n) { int sum 0; for (int i 0; i n; i) { int x; cin x; sum x; } cout sum endl; // endl 会换行并刷新缓冲区 } return 0; }逻辑说明while (cin n)是 levoj 多组输入题的标准写法它等价于“只要还能读到一个整数 n就继续处理”。sum必须在每组开始时重置为 0否则上一组的结果会累加进来这是新手最常见的错误之一。endl和\n的区别在于endl会刷新输出缓冲区对于大量输出的题目用\n更快但 levoj 数据量一般不大用endl更直观。参数说明n是每组的数据个数x是临时读入的每个数sum是累加器。注意sum的类型如果 n 和每个数都可能很大int可能溢出需要换成long long。levoj 有些题会故意卡 int 溢出看到“和”字就要警惕。3.3 Python 实现与输入处理差异import sys # sys.stdin 可以迭代读取所有行适合多组输入 for line in sys.stdin: line line.strip() if not line: continue n int(line) # 下一行是 n 个数但可能分多行所以用循环读够 n 个 nums [] while len(nums) n: nums.extend(map(int, sys.stdin.readline().split())) print(sum(nums))Python 处理多组输入时sys.stdin的迭代方式更灵活但要注意题目是否保证每组数据严格两行。如果不保证就需要像上面这样用while len(nums) n来读够数量。strip()用来去掉行末换行符if not line: continue跳过空行。print(sum(nums))默认换行符合输出要求。注意Python 的input()在遇到 EOF 时会抛EOFError所以多组输入推荐用sys.stdin不要用input()裸循环。3.4 本地测试与提交前检查清单写完代码先在本地用样例测。样例过了之后自己造几个边界用例n1、n0如果允许、有负数、有零、最大 n。每个用例手算预期输出和程序输出对比。提交前检查文件是否有多余输出比如调试用的打印语句、输出格式是否和题目要求完全一致空格、换行、大小写、变量类型是否可能溢出、数组大小是否够用。我自己的习惯是提交前把代码从头到尾读一遍重点看循环边界和变量初始化。很多 WA 不是逻辑错而是sum没清零、数组开小了、循环多跑了一次或少跑了一次。这些低级错误在 levoj 上很常见但完全可以通过检查清单避免。4. levoj 常见题型避坑与排查那些年我踩过的 WA 和 TLE4.1 多组输入处理不当导致只过第一组现象样例过了提交后只过第一个测试点后面全 WA。原因题目要求多组输入但代码只处理了一组或者循环条件写错。比如用了if (cin n)而不是while (cin n)或者 Python 里只调用了一次input()。解决确认题目是否有多组输入字样统一用while (cin n)或for line in sys.stdin处理。如果不确定看题目描述里有没有“多组”“若干组”“输入包含多组测试数据”这类词。4.2 输出格式多一个空格或少一个换行现象提交后返回 Presentation Error 或 WA但本地输出和样例看起来一模一样。原因levoj 对输出格式极其严格行末多一个空格、最后一行多一个空行、数字之间分隔符不对都会判错。解决用diff命令对比自己的输出和样例输出或者把输出重定向到文件用编辑器显示不可见字符。常见坑点每组输出后是否要空行、最后一个数字后是否有空格、字符串是否要原样输出。我一般会在输出逻辑里加条件判断确保最后一个元素后不加多余分隔符。4.3 数组开小或变量类型溢出现象本地小数据能过提交后 WA 或 Runtime Error。原因数组大小按样例的 n 来开但测试数据里 n 可能更大或者int存不下累加结果。解决看题目描述里的数据范围数组开到范围上限再加一点余量。累加和、乘积这类运算如果范围超过 2×10^9就用long long。levoj 有些题会明确写“答案可能很大”这就是提示你要用大整数或long long。4.4 字符串输入用 cin 导致读不到空格现象题目要求读入一行包含空格的字符串但用cin s只读到了第一个单词。原因cin 以空格、制表符、换行符为分隔符遇到空格就停止。解决用getline(cin, s)读整行但要注意如果前面用过cin 缓冲区里可能残留换行符需要先用cin.ignore()清掉。Python 里用sys.stdin.readline().strip()或input().strip()读整行。4.5 递归太深导致栈溢出现象递归题本地小数据能过提交后 Runtime Error 或段错误。原因递归深度超过系统栈限制levoj 的栈空间可能比本地小。解决把递归改成迭代或者手动增大栈空间不推荐比赛环境不可控。更常见的做法是加记忆化减少重复计算同时降低递归深度。如果题目本身要求递归检查递归终止条件是否正确避免无限递归。5. 把参考答案变成自己的东西验证与进阶技巧5.1 用对拍验证自己的代码对拍是验证代码正确性的利器。写一个暴力程序保证正确但可能慢和一个待测程序你的提交代码再写一个随机数据生成器循环运行两个程序比较输出是否一致。如果发现不一致保存那组数据手动分析。对拍能帮你发现那些样例覆盖不到的边界情况。# 对拍脚本示例bash for i in $(seq 1 1000); do python gen.py input.txt # 生成随机数据 ./brute input.txt out1.txt ./mine input.txt out2.txt if ! diff -q out1.txt out2.txt /dev/null; then echo Difference found at test $i cat input.txt break fi done逻辑说明gen.py生成随机输入brute是暴力程序mine是你的程序。diff -q静默比较发现不同就输出测试数据并退出。参数说明seq 1 1000表示跑 1000 组可以根据需要调整。对拍的关键是暴力程序必须绝对正确数据生成器要覆盖各种边界。5.2 从 AC 到讲清楚写题解的习惯过了题不算完试着把这道题的思路、坑点、复杂度分析写下来。写题解的过程会逼你理清逻辑发现那些“好像懂了但说不清”的地方。我一般会写题目大意、思路推导、关键代码、易错点、复杂度。写完之后如果能让别人看懂并复现说明你真的掌握了。levoj 上很多题都有讨论区看看别人的解法对比自己的能学到新技巧。5.3 用 levoj 题目训练调试能力调试能力比写代码能力更重要。遇到 WA不要急着改代码先定位问题。我习惯用三种方法打印中间变量、缩小输入规模、二分查找错误位置。打印中间变量最直接但记得提交前删掉。缩小输入规模是把大测试用例改成小用例手动跟踪。二分查找是如果程序在处理某个输入时出错把输入分成两半看哪一半导致错误。这些方法能帮你快速定位问题而不是盲目改代码。5.4 建立自己的模板库刷多了会发现很多题有固定套路。比如多组输入、字符串分割、排序、二分查找、简单 DP。把这些套路写成模板下次遇到直接套。模板要简洁只保留核心逻辑参数可配置。我自己的模板库里有多组输入模板、快速排序模板、二分查找模板、并查集模板、简单 DP 模板。每次遇到新题先看能不能套模板不能套再想新解法。这样能大幅提高刷题效率。最后说个血泪经验别迷信参考答案。参考答案可能不是最优解甚至可能有 bug。我见过一份 levoj 参考答案里数组开小了只是测试数据恰好没卡到。所以拿到参考答案先自己跑一遍再造几个边界用例测确认没问题再参考。刷题的核心是训练思维不是收集代码。希望帮到你。本文还有配套的精品资源点击获取