简介基于Python的算法竞赛题目设计源码工具面向算法竞赛出题人、OJ平台管理员与编程教师解决题目格式统一难、样例测试繁琐、题目分发不便等痛点覆盖从题目配置、模板生成到答案校验的完整流程。包内共78个文件约7.85MB核心包括15个Python自动化脚本、14个Jinja模板、7个JSON配置及多个Markdown文档同时提供输入输出样例、答案文件、PNG图示和跨平台格式支持每一类文件都有明确用途目录结构便于快速定位。已有325人浏览学习适合算法竞赛出题、OJ题目建设、编程教学与公开课练习设计等场景。资源不仅包含可直接运行的题目生成与打包工具还附带竞赛专用LaTeX/HTML模板、Git忽略规则及多平台可执行文件能帮助用户快速搭建个人题库工作流也可作为二次开发与教学演示的基础。1. 基于Python的算法竞赛题目设计源码工具出题人到底在做什么一场算法竞赛最磨人的环节往往不是选手写代码而是出题人等着数据生成完毕却发现生成的输出文件和题目预期对不上。本地跑一遍样例、交到OJ上却判Wa最后定位到是题面里一个边界条件没有落到数据生成器里。这个基于Python的算法竞赛题目设计源码工具核心就是把“出题”从手工造数据、肉眼对答案变成一套可重复、可版本管理的工程流程。它解决的问题很具体批量生成覆盖边界的测试数据、自动构造高压力数据、用校验器统一检查输出格式、把题目三元组题面、数据、标程打包成可发布的结构。适合三类人——带学生打比赛需要定期出题的教练、把训练平台内容当核心资产的运营方、以及想在本地用Python快速验证一道题数据强度的个人选手。工具的本质不是抢出题人的判断力而是把判断力固化成代码。数据生成一次只能跑出少量样例真正有价值的是一套能随时重新生成、重新校验、重新打包的源码工程。2. 数据生成的源码骨架从随机数到边界数据2.1 为什么题目设计要先写数据生成器而不是先写标程出题人最常犯的顺序错误是先把标准程序写好、跑几组样例就开始写题面。这样做的后果是数据强度完全靠运气题目发布后选手提交各种边界输入标程却根本没验证过。正确的顺序是题面定义了输入输出约束先写数据生成器生成一个覆盖范围的原始数据池再拿标程去跑数据池跑不通的地方就是逻辑矛盾和边界漏洞。生成器的代码不需要复杂但必须带三个属性确定性种子固定后结果可复现、可调参数数据规模、值域、极端比例、可写的文件输出。下面这个例子是经典结构——从纯随机构造向结构化构造过渡。import random import os def gen_sequence(max_n, max_val, moderandom, seed20240501): random.seed(seed) if mode random: n random.randint(1, max_n) arr [random.randint(1, max_val) for _ in range(n)] elif mode sorted: n max_n arr sorted(random.randint(1, max_val) for _ in range(n)) elif mode reverse: n max_n arr sorted((random.randint(1, max_val) for _ in range(n)), reverseTrue) else: raise ValueError(unknown mode) return n, arr def write_data(filename, n, arr): with open(filename, w, encodingutf-8) as f: f.write(f{n}\n) f.write( .join(map(str, arr)) \n)逻辑说明mode参数控制生成模式random是均匀随机sorted和reverse分别模拟已排序的输入这在测二分和单调栈类题目时极其常见。seed不随机分配而作为参数传入是为了同一道题在不同机器上重新生成数据时结果一致这是一套源码工具的首要要求。参数说明max_n控制规模上限建议从 10^3 到 10^6 分档max_val要贴着题面给的值域下界和上界写避免生成器的值域比题面宽或窄——比题面宽会让数据超过题目约束比题面窄则覆盖不到上界。2.2 构造“卡掉错误算法”的数据造数据的大头不是随机伪随机数据只能覆盖到概率比较大的路径真正考验题目质量的是针对性数据。比如一个要求 O(nlogn) 的题目如果随机数据里恰好有大量重复元素一个错误的 O(n^2) 冒泡排序也可能蒙混过关。构造卡数据的手段通常有三类最坏情况模式、密集重复模式、递增递减夹逼模式。以“给定数组求最长不下降子序列长度”为例最坏情况对动态规划解法不敏感但对暴力法非常敏感。下面这段代码展示了如何在一个生成批次里同时产出“随机小数据”“上升大数据”“完全逆序数据”三种文件。def gen_all_cases(base_dir, n_small20, n_big200000): os.makedirs(base_dir, exist_okTrue) cases [ (random_small, lambda: gen_sequence(n_small, 10**9, random, seed1)), (sorted_big, lambda: gen_sequence(n_big, 10**9, sorted, seed2)), (reverse_big, lambda: gen_sequence(n_big, 10**9, reverse, seed3)), ] for name, fn in cases: n, arr fn() write_data(os.path.join(base_dir, f{name}.in), n, arr)逻辑说明gen_all_cases不把文件名写死而是用name区分不同模式统一输出.in后缀。数据文件命名不加中文避免OJ读取时遇到编码问题。seed在每个模式里显式指定保证重跑只会覆盖同名文件不会产生“多跑一次多一组数据”的混乱。一个小建议生成器尽量写成命令行可调参数的形式而不是每次改源码。至少留出--seed、--output-dir两个入口这能让后续批量生成大测试集时不用反复改代码。3. 标程与校验器把逻辑绑定成机器可判的规则3.1 标程不是“能跑的代码”而是“所有数据对齐的中心”数据生成器产出输入文件后标程负责产出对应的输出文件。这里有个常见误会标程只要在样例上正确就行。实际上标程是数据合法性的第一道闸门。如果标程在某个生成数据上运行超时说明数据规模超出题面承诺的时间限制如果标程报错说明生成器造出了违反输入约束的数据。因此标程文件需要和生成器放在同一个工具目录下由工具统一调度。标准流程是解析参数 → 循环生成数据 → 调用标程 → 校验输出 → 归档。下面这个调度脚本把整个流程串起来。import subprocess import sys def run_std_solution(input_file, solver_cmd): with open(input_file, r, encodingutf-8) as f_in: data f_in.read() result subprocess.run( solver_cmd, inputdata, capture_outputTrue, textTrue, timeout5, ) if result.returncode ! 0: raise RuntimeError(fsolver failed on {input_file}: {result.stderr}) return result.stdout def validate_input(input_file): # 校验器只检查格式和范围不检查逻辑 with open(input_file, r, encodingutf-8) as f: first_line f.readline().strip() n int(first_line) second_line f.readline().strip() nums list(map(int, second_line.split())) assert n len(nums), fn{n}, len{len(nums)} assert all(1 x 10**9 for x in nums), value out of range逻辑说明run_std_solution用subprocess.run把生成好的输入通过标准输入传给标程capture_outputTrue拿到标准输出timeout参数防止死循环占死整个批次。validate_input是轻量格式校验它不判断答案对错只检查数据是否符合题面约束这是把“数据合法性”与“答案正确性”分离的关键。这里的取舍是标程回归测试放在生成之后、正式打包之前一旦发现输出文件与预期不符立刻中断整个批次而不是等全部数据跑完再回头看。中断得越早浪费的时间越少。3.2 特殊判题Special Judge工具当答案不是唯一解时很多题目不只有单一标准答案。比如输出任意合法解、允许浮点误差、或者多解按评分规则给部分分。这个时候标程跑出来的输出文件只能作为参考不能作为唯一标答。常见做法是把标程的输出交给一个评委程序special judge逐项比对而不是整文件比对。简易 spj 的 Python 实现可以写成这样读取选手输出与标准输出按行切分对浮点字段用绝对误差或相对误差判断。def judge_float(num_out, num_std, eps1e-6): if abs(num_out - num_std) eps: return True if abs(num_out - num_std) eps * max(abs(num_out), abs(num_std)): return True return False def spj_line_by_line(out_path, std_path, eps1e-6): with open(out_path, r, encodingutf-8) as fo, open(std_path, r, encodingutf-8) as fs: lines_out fo.read().strip().splitlines() lines_std fs.read().strip().splitlines() if len(lines_out) ! len(lines_std): return False for lo, ls in zip(lines_out, lines_std): a_out list(map(float, lo.split())) a_std list(map(float, ls.split())) if len(a_out) ! len(a_std): return False for x, y in zip(a_out, a_std): if not judge_float(x, y, eps): return False return True逻辑说明judge_float先做绝对误差判断再做相对误差判断两个条件满足一个就算通过。这个策略对齐了大多数OJ对浮点答案的常见容忍度——数据小时看绝对误差数据大时看相对误差eps 通常取 1e-6。spj_line_by_line按行比较同时要求行数和每行元素个数一致防止选手输出换行位置错乱。参数说明这里有个容易忽略的点整文件strip()之后按splitlines()处理会忽略文末多余换行但不会忽略多余空行。出题时最好在 spj 里额外加一道“空行过滤”否则选手输出多一个空行就会被判Wa造成体验很差。4. 避坑算法竞赛题目设计工具的5个高频坑4.1 坑一Windows下生成的数据文件里混入\r\n评测机读挂现象本地生成数据后标程跑得很正常传到Linux评测机上判题时读取第一个数字直接报错或者输出答案全部错误。原因用open(filename, w)写入但没指定换行符Windows默认写成\r\n而OJ上的读入程序大多只按\n处理把\r当成数据的一部分。解决写生成器时统一指定newline\n或者在读入端用split()而不是splitlines()来容错。with open(filename, w, encodingutf-8, newline\n) as f: f.write(...)4.2 坑二标程和数据生成器吃同一份随机种子导致数据和答案对不上现象数据生成器每次重跑都产生不同数据而标程跑的是旧数据归档时输入和输出文件错位。原因生成器里把random.seed()放在循环外每一次生成调用都会推进随机状态但标程结果还没同步更新。解决在工具入口处固定全局种子并且把“生成—运行标程—写答案文件”设计成一个不可分割的调用链一次执行只对应一个数据版本。这条务必写进团队约定里。4.3 坑三校验器只查了格式没查边界值现象题面写1 a_i 10^9数据生成器却生成了a_i 0选手提交绝对值很大的算法也能过但出题人拿自己标程跑却AC了全部数据。原因validate_input只检查了数组长度和空行忘了用题面约束逐个字段判断。解决把题面的每一段数值约束直接翻译成断言。如果题目值域分段要按段分开断言。这些断言是源码工具里最容易继承的资产。4.4 坑四spj 浮点误差判断写反了实际允差被放大十倍现象部分分判题时误差在 1e-5 的答案被误判为正确而在 1e-7 的答案又被判错。原因abs(num_out - num_std) eps * max(abs(num_out), abs(num_std))里的max写成min导致数值大时相对误差被放大。解决写完后用一组已知偏移的假输出做单测——分别偏移 1e-3、1e-7、1e-9确认阈值边界行为符合预期。assert spj_line_by_line(out_bad.txt, std.txt, 1e-6) False assert spj_line_by_line(out_good.txt, std.txt, 1e-6) True4.5 坑五工具目录没有版本管理改了一版题面忘了改数据现象题目改了数据范围从10^5 改成10^6生成器参数同步改了但旧数据文件留在目录里没删打包时把新旧两套数据混在一起评测机只识别编号连续的.in/.ans文件出现空档直接跳过。原因数据文件和源码工具没有纳入同一套版本管理。解决每个题目一个独立目录并配置.gitignore忽略生成的.in/.ans只提交生成器、标程、校验器和题面源文件。生成物用脚本重新生成避免手工清理遗漏。5. 把题目设计源码工具变成团队资产进入“可复用”阶段5.1 用配置文件管理题目元数据工具用久了最核心的复用不是复制代码而是复制“出题的规则”。建议在题目目录里放一个problem.yaml这样的元数据文件把题名、时间限制、内存限制、生成器参数、spj 开关集中管理。生成数据时由脚本读取配置而不是在生成器代码里硬编码所有参数。这能让一道题的移植成本降低到只改配置。5.2 批量回归与打包脚本准备阶段把全部数据跑一遍标程和校验器用一条命令完成批量回归同时输出一张摘要表。这张表列清楚每个数据文件的 n、模式、生成时间、标程耗时方便出题评审时快速判断数据强度边界。打包时再额外生成一份清单文件写明数据文件与题目约束的对应关系这样把数据交接给OJ管理员时不需要口头解释。5.3 从工具到习惯我把这个工具沉淀下来的最大体会是出题的速度不会因为写了生成器而变快但题目质量的下限会被拉得很高。以前一道题容易因为数据不严在赛后被人诟病现在每次生成数据后都跑一遍针对性构造用例这种行为本身比工具更重要。希望这些拆解能帮你在下一次出题时少走几步弯路。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
pnpm 软件包管理器速查指南:常用命令、Monorepo 工作区与高级用法详解 pnpm 软件包管理器速查指南:常用命令、Monorepo 工作区与高级用法详解 【免费下载链接】reference 为开发人员分享快速参考备忘清单(速查表) 项目地址: https://gitcode.com/jaywcjlove/reference
本指南基于开源参考仓库 jaywcjlove/reference 中的 docs/pn… · 2026/9/23 15:30:27
GB28181播放自愈三要素:NACK、TCP降级与双缓冲协同机制 1. GB28181流媒体播放“卡死”背后的真相:不是网络差,是协议层自愈机制彻底失能你有没有遇到过这样的场景:GB28181平台接入了20路海康/大华IPC,白天一切正常,一到下午网络稍有抖动,某几路画面就突然卡住、花… · 2026/9/23 15:30:27
基于WEB的毕业生招聘系统:从需求设计到答辩通关指南 简介:一份面向Java方向毕业设计的网络招聘系统完整项目资源,适合正在准备毕业设计或想学习JSP/Servlet开发的计算机专业学生。项目采用B/S三层结构,结合JSP、JavaBean、JDBC等技术,围绕求职者、用人单位和管理员三类用户实现职位发… · 2026/9/23 15:30:27
DRAM存储芯片研究框架:从DDR4/DDR5协议到颗粒选型与稳定性验证 简介:这份资源是方正证券2021年4月发布的半导体行业DRAM深度研究报告,共71页,面向半导体产业研究者、投资分析人员及电子产业从业者,系统梳理存储芯片的研究框架与投资逻辑。压缩包内为1个PDF文件,大小约4.41MB&#x… · 2026/9/23 16:12:40
JSQMessagesViewController 8.0.0 升级指南:破坏性变更、新特性与源码级解读 UI组件即时通讯 【免费下载链接】JSQMessagesViewController An elegant messages UI library for iOS 项目地址: https://gitcode.com/gh_mirrors/js/JSQMessagesViewController 点击查看 免费下载 本文以 JSQMessagesViewController 官方 CHANGELOG.md 中 8.0.0 … · 2026/9/23 16:12:40
PCIe 4.0/5.0与NVMe SSD测试技术:协议、工具与实战 简介:这份白皮书面向从事PCIe Gen 4&5高速总线开发的芯片、模块、插卡与系统研发测试工程师,系统梳理协议层及以上的分析、诊断与测试工具选型思路,帮助解决Gen5总线问题定位、兼容性验证与测试环境搭建等实际难题。资源为单一PDF文档&am… · 2026/9/23 16:12:40
入职联想Agent开发岗35K,面试水的很不用提前焦虑的 一听到Agent,就在想:
Agent 开发到底是不是一个泡沫?
现在能不能学这个 Agent 开发?
社招的人怎么去朝 Agent 转型?
但其实Agent开发是一个很广的岗位,它是需要业务驱动的。目前市场上的很多求职者&… · 2026/9/23 16:12:33
告别b26报错:3步定位Stack Trace,附完整示例与源码解析 告别b26报错:3步定位Stack Trace,附完整示例与源码解析 报错一堆看不懂 StackTrace?别慌,这不是你的错,是工具没喂饱你。今天不聊虚的,直接上 b26 相关的 完整示例 ,带你从一行堆栈日志挖到源码底层。… · 2026/9/23 16:12:33
segmentation-models-pytorch 安装指南:PyPI 一键安装、源码构建与开发环境配置全解析 人工智能深度学习计算机视觉 【免费下载链接】segmentation_models.pytorch Semantic segmentation models with 500 pretrained convolutional and transformer-based backbones. 项目地址: https://gitcode.com/gh_mirrors/se/segmentation_models.pytorch 点击查… · 2026/9/23 16:12:33
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29