免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

西南科技大学OJ代码合集:刷题存档与本地对拍验证指南

西南科技大学OJ代码合集:刷题存档与本地对拍验证指南 简介这份资源是西南科技大学OJ的代码合集面向计算机专业学生、算法竞赛入门者以及需要刷题巩固基础的编程爱好者帮助解决在线评测题目无从下手、缺少参考解法的问题。压缩包共117个文件以110个cpp源码为主体另含readme说明、license授权、gitignore及md文档整体仅20KB轻量便于携带与查阅。内容覆盖哈夫曼译码、单链表信息分类、中缀转后缀、一元多项式加法、Prim最小生成树、二叉排序树查找等典型题目涉及数据结构、图论与算法设计等方向代码均以AC为目标经过测试与优化。目前已有183人学习。读者可从中获取可直接编译运行的参考实现理解输入输出格式处理、边界情况判断与性能优化思路并借助目录结构按知识点检索适合作为课程实验与赛前训练的对照材料。1. 西南科技大学 OJ 代码合集一份能直接跑通的刷题存档如果你正在西南科技大学 OJ 上刷题或者准备用这套题单做 C/C、数据结构、算法的集中训练这份「西南科技大学 oj 的代码合集.7z」大概率能帮你省下大量重复造轮子的时间。它不是教程也不是题解博客而是一份按题目编号或题名归档的源码压缩包覆盖了从基础语法、循环分支到数组、字符串、结构体、递归、排序查找再到链表、栈队列、树、图等典型 OJ 题型。适合两类人一是刚注册 OJ 账号、想对照可运行代码理解题意的新手二是已经能写题、但想快速核对边界处理和输入输出格式的老手。需要提醒的是直接抄代码过题没有意义这份资源真正的价值在于「对照调试」——把别人的实现跑一遍再改参数、换数据看哪里会翻车。下面按「资源结构 → 环境配置 → 典型题型复现 → 避坑 → 进阶验证」的顺序拆开讲。2. 解压后先看什么目录结构、文件命名与编译环境拿到 .7z 之后不要急着双击运行先确认压缩包完整性和内部组织方式。常见做法是用 7-Zip 或 Bandizip 解压到纯英文路径避免中文目录导致部分 IDE 或命令行编译器读文件失败。解压后一般能看到按题号或题名分文件夹的结构每个文件夹里放 .cpp、.c 或 .py 源文件少数题目会附带 input.txt / output.txt 用于本地对拍。2.1 目录命名规律与快速定位题目先看顶层目录。如果文件夹名是纯数字比如1001、1002那基本对应 OJ 题号如果是AB Problem、成绩转换这类中文题名说明作者按题目名称归档。两种方式各有优劣题号定位快但换一套 OJ 就失效题名可读性好但搜索时要注意全角半角空格。我一般会先跑一条命令把目录树打印出来确认总题量和文件类型分布# 查看解压后的目录结构只列出两层避免输出过长 find . -maxdepth 2 -type d | sort # 统计 .cpp / .c / .py 文件数量判断主要语言 find . -type f \( -name *.cpp -o -name *.c -o -name *.py \) | wc -l # 查看某个题号文件夹里到底有什么 ls -la ./1001/第一条命令帮你快速看清归档逻辑第二条统计源码数量心里有数第三条确认单题文件夹里是否包含测试数据。如果发现只有源码没有测试数据那本地验证就得自己造样例后面会讲怎么造。2.2 编译器与运行环境的最低要求这份合集里的 C/C 代码通常用 GCC 就能编译但要注意标准版本。老题可能用 C98 写法新题可能用了auto、vector、unordered_map等 C11 及以上特性。我一般统一用g -stdc17编译兼容性最好。Python 代码则要注意 Python 2 和 Python 3 的 print 差异如果文件里出现print xxx那就是 Python 2 写法需要手动改。# 编译单个 C 文件开启常用警告便于发现潜在问题 g -stdc17 -Wall -O2 -o solution ./1001/main.cpp # 运行并手动输入测试数据 ./solution # 如果有 input.txt可以直接重定向 ./solution input.txt # Python 文件先确认版本 python3 --version python3 ./1002/main.py input.txt-Wall打开常见警告能提前暴露未初始化变量、类型截断等问题-O2是 OJ 常用优化级别本地开同级别更接近真实判题环境。重定向输入是本地对拍的基础后面讲批量验证时会反复用到。提示如果解压后出现乱码文件名多半是压缩时用了 GBK 编码在 Windows 上用 7-Zip 打开时手动选「简体中文」代码页即可不要直接改文件名否则可能对不上题号。3. 从 AB 到图论典型题型的代码复现与参数调整这一章挑几类 OJ 高频题型把合集里的代码拉出来跑一遍重点讲「怎么改、改哪里、为什么这样改」。每类题型给一个可抄的代码骨架并说明输入输出格式的常见坑。3.1 输入输出格式最容易被忽略的翻车点OJ 题最玄学的地方不是算法而是输入输出格式。合集里很多代码第一眼能看懂但直接复制到自己的账号上提交却报「Presentation Error」或「Wrong Answer」八成是空格、换行、多组数据读取的问题。常见的有三种单组数据、多组数据直到 EOF、先给 T 再给 T 组。下面这个骨架覆盖了多组读取的标准写法#include iostream using namespace std; int main() { int a, b; // 多组数据直到文件结束OJ 常用写法 while (cin a b) { cout a b endl; // 注意 endl 会刷新缓冲区量大时可用 \n } return 0; }while (cin a b)是 C 里处理「未知组数」的标准做法等价于scanf返回 EOF 判断。endl会强制刷新输出缓冲区数据量特别大时可能拖慢速度换成\n更稳。如果题目要求「每组输出后空一行」那就要在循环里额外加一个cout endl;但最后一组后面是否空行要看题目描述这里最容易翻车。3.2 数组与字符串边界下标和结束符数组题的核心就两件事开多大、下标从哪开始。合集里有些代码为了省事开了int a[1005]如果题目数据范围是 10^5那就直接越界。我一般会先看题目里的「数据范围」再决定数组大小并且习惯多开 5 到 10 个冗余。字符串题则要注意 C 风格字符串的\0和strlen的返回值类型。#include cstdio #include cstring const int MAXN 100005; // 根据题目数据范围调整多开一点防越界 int a[MAXN]; int main() { int n; scanf(%d, n); for (int i 0; i n; i) { scanf(%d, a[i]); } // 求最大值和最小值注意初始化不要用 0防止全负数时出错 int mx a[0], mn a[0]; for (int i 1; i n; i) { if (a[i] mx) mx a[i]; if (a[i] mn) mn a[i]; } printf(%d %d\n, mx, mn); return 0; }MAXN是编译期常量方便统一改。mx和mn初始化为a[0]而不是 0这是血泪经验如果数据全是负数初始化为 0 会导致最大值永远为 0。字符串题里char s[1005]读入后末尾自动有\0但如果你手动逐字符赋值记得补上否则printf(%s)会一直输出到内存里的随机位置。3.3 排序与查找qsort、sort 和二分边界排序题合集里一般用std::sort老代码可能用qsort。两者都能用但sort更安全因为qsort的比较函数返回int写错符号会导致排序结果不稳定甚至崩溃。二分查找则要注意mid的取法和循环条件while (l r)和while (l r)对应不同的边界处理。#include iostream #include algorithm using namespace std; const int MAXN 100005; int a[MAXN]; int main() { int n, target; cin n target; for (int i 0; i n; i) cin a[i]; sort(a, a n); // 默认升序降序用 greaterint() // 二分查找 target 是否存在 int l 0, r n - 1, pos -1; while (l r) { int mid l (r - l) / 2; // 防止 lr 溢出 if (a[mid] target) { pos mid; break; } else if (a[mid] target) l mid 1; else r mid - 1; } cout (pos -1 ? not found : found) endl; return 0; }mid l (r - l) / 2比(l r) / 2更稳避免l r超过int范围。sort默认升序降序写sort(a, a n, greaterint())。如果题目要求「按绝对值排序」或「结构体多关键字排序」就要自己写比较函数注意比较函数必须是严格弱序不能写否则可能运行时错误。3.4 链表、栈与队列手写和 STL 的取舍合集里有些题要求手写链表有些直接用stack、queue。手写链表能练指针操作但 OJ 上更容易出段错误STL 版本代码短但要注意pop()不返回元素得先取top()或front()。我一般建议如果题目不限制 STL优先用 STL 保证正确率如果题目明确要求「不得使用 STL」再手写。#include iostream #include stack #include string using namespace std; int main() { string s; cin s; stackchar st; for (char c : s) { if (c ( || c [ || c {) { st.push(c); } else { if (st.empty()) { cout no endl; return 0; } char top st.top(); st.pop(); if ((c ) top ! () || (c ] top ! [) || (c } top ! {)) { cout no endl; return 0; } } } cout (st.empty() ? yes : no) endl; return 0; }这是括号匹配的经典写法。st.empty()判断必须在top()之前否则空栈取顶会未定义行为。pop()只删除不返回所以先top()再pop()。如果题目数据量到 10^6stackchar可能稍慢可以换vectorchar手动模拟但一般 OJ 不会卡这么死。4. 本地对拍与批量验证别只靠眼睛看代码合集里的代码能不能直接过题不能靠肉眼判断。我一般会做两件事一是用题目自带的样例跑一遍二是自己造随机数据对拍。对拍的核心是「一个暴力程序 一个待测程序 数据生成器」三者循环比较输出。4.1 用脚本批量编译和运行如果合集里有几十上百个文件手动一个个编译不现实。写个 shell 脚本批量跑把编译失败和运行超时的文件挑出来#!/bin/bash # 批量编译当前目录下所有 .cpp 文件输出结果到 compile_log.txt compile_log.txt for f in $(find . -name *.cpp); do out${f%.cpp}.out if g -stdc17 -Wall -O2 -o $out $f 2compile_log.txt; then echo OK: $f compile_log.txt else echo FAIL: $f compile_log.txt fi donefind . -name *.cpp递归找所有源文件${f%.cpp}.out把扩展名替换成可执行文件2compile_log.txt把编译错误追加到日志。跑完后打开日志先看FAIL的行那些就是语法或头文件问题优先修。4.2 随机数据生成与对拍模板对拍需要三个文件gen.cpp生成随机输入brute.cpp是暴力正确解test.cpp是待测代码。下面是一个通用对拍脚本#!/bin/bash # 对拍脚本gen 生成数据brute 和 test 分别运行比较输出 for i in $(seq 1 1000); do ./gen input.txt ./brute input.txt output_brute.txt ./test input.txt output_test.txt if ! diff -q output_brute.txt output_test.txt /dev/null; then echo Difference found at case $i cat input.txt break fi done echo Doneseq 1 1000表示跑 1000 组diff -q只判断是否不同不输出具体差异发现不同就打印当前输入并退出。这样能快速定位是哪组数据让待测代码翻车。注意gen里的随机范围要和题目数据范围一致否则对拍没有意义。注意对拍脚本里的brute必须是绝对正确的暴力解不能也用待测代码否则等于自己跟自己比永远发现不了问题。5. 避坑与常见问题这份合集最容易翻车的五个地方5.1 现象编译报错auto not declared或unordered_map not found原因代码用了 C11 及以上特性但编译时没指定标准默认可能是 C98。解决编译命令加-stdc11或-stdc17例如g -stdc17 -o solution main.cpp。如果 OJ 本身只支持 C98那就得把auto改成具体类型把unordered_map换成map。5.2 现象本地运行正常提交后报「Runtime Error」原因数组开太小导致越界或者递归太深导致栈溢出。解决先看题目数据范围把数组大小调到范围上限再加 5递归题如果深度可能到 10^5改成迭代写法或手动开大栈空间。本地可以用ulimit -s unlimited临时放开栈限制但 OJ 上不一定允许。5.3 现象输出结果和样例一模一样但提交报「Presentation Error」原因行末多了空格或者最后一组数据后多输出了空行。解决逐行对比样例输出注意printf(%d , x)这种带尾空格的写法多组数据时判断是否是最后一组最后一组不输出多余换行。有些 OJ 对行末空格不敏感但严格判题会卡。5.4 现象多组数据只处理了第一组原因while (cin n)写成了if (cin n)或者scanf没判断返回值。解决多组数据统一用while循环C 语言写while (scanf(%d, n) ! EOF)C 写while (cin n)。如果题目先给 T那就for (int i 0; i T; i)不要混用。5.5 现象浮点数答案「差一点」被判错原因浮点数比较用了或者输出精度不够。解决比较时用fabs(a - b) 1e-6输出时按题目要求保留小数位printf(%.2f, x)或cout fixed setprecision(2) x。如果题目要求「误差不超过 1e-6」那输出精度至少给到 1e-7。6. 进阶用法把代码合集变成自己的题单索引这份合集最大的价值不是「抄」而是「建索引」。我一般会做一张表把题号、题名、考点、易错点、对应源码路径记下来下次遇到同类题直接翻表。比如下面这种结构题号题名考点易错点源码路径1001AB Problem输入输出多组读取./1001/main.cpp1002成绩转换分支边界 90/60./1002/main.cpp1003最大最小值数组遍历全负数初始化./1003/main.cpp1004括号匹配栈空栈取顶./1004/main.cpp建表之后再写一个简单的 Python 脚本按关键词搜索源码文件比如输入「栈」就列出所有包含stack的文件import os def search_code(root, keyword): for dirpath, _, filenames in os.walk(root): for name in filenames: if name.endswith((.cpp, .c, .py)): path os.path.join(dirpath, name) with open(path, r, encodingutf-8, errorsignore) as f: content f.read() if keyword in content: print(path) # 搜索包含 stack 的源码文件 search_code(., stack)os.walk递归遍历目录errorsignore防止个别文件编码问题导致脚本中断keyword可以换成queue、sort、dfs等。这样合集就从「一堆文件」变成了「可检索的题库」。从那以后我每次拿到新的 OJ 代码包都会先跑一遍批量编译再建索引表最后挑几道典型题对拍验证。这套流程走下来基本能摸清一份合集的真实可用度也能避开大部分格式和边界坑。希望帮到你。本文还有配套的精品资源点击获取
返回列表