NOI Linux 虚拟机 · 官方测点评测
把官方测试数据 + 学生源码放进 VirtualBox 的 NOI Linux 虚拟机,用 Arbiter 同口径判题,
输出逐人逐题分数、与官方成绩的差异清单、多组口径横评,并保留可复跑的原始结果。
- 判题口径与 Arbiter 配置格式:
references/judge-rules.md、references/arbiter-format.md - 虚拟机操作与稳定性:
references/vm-ops.md - 已跑过的实战案例(CSP-J/S 2026):
references/case-csp2026.md - 可复用脚本:
scripts/(判题 / 准备 / 启动 / 出报告)
输入确认(缺一先问,不许猜)
- 官方数据目录(含
data/<题目><i>.in|.ans)与学生源码目录(<准考证>/<题目>/<题目>.cpp)。 - 官方成绩表(逐人逐题分数,用于对比)与姓名→准考证映射。
- 每道题时限(各题可能不同,必须逐题核对题面;如 2026 S 组 hub=3s、其余 1s)。
- 评测范围:哪些学生/哪些题(不必跑整个比赛名单)。
环境(首次准备)
- VirtualBox VM(NOI Linux / Ubuntu 20.04),建议 12GB 内存 / 8 vCPU(GUI+编译+判题并发时 8GB 会卡死)。
- 虚拟机内 Arbiter:
/usr/local/arbiter/local/arbiter_local;比赛目录~/Desktop/<CONTEST>。 - Windows ↔ 虚拟机共享目录:
C:\Users\sonic\VMShare↔/media/sf_VMShare。 - 客户机用户
vboxuser;命令走VBoxManage guestcontrol(见 vm-ops.md)。
流程
1. 准备比赛目录与数据
- 比赛目录按 Arbiter 标准格式(
setup.cfg/day1.info/task1_*.info/players/day1/...),
新题可参考references/arbiter-format.md。 - 逐题核对时限并写进
task1_*.info的LIMIT=(秒)。 - 确认每题的
CCL=cpp@g++ -O2 -std=c++14 -o %o %i、PLUG=mlss_filterspace_e(CCF 口径),
不是fulltext_e(后者对行末空格/末尾换行过严)。修改前先备份task*.info。 - 官方数据按
<题目><i>.in/.ans放进evaldata/(不要放 zip);可选:再复制一份到/dev/shm/evaldata内存盘。
2. 虚拟机内准备(每次开跑前)
bash scripts/vm_prep.sh <CONTEST_DIR> <DATA_SRC_DIR> <TMPFS_DATA_DIR> <LOCAL_OUT_DIR>
做四件事:杀残留判题进程 → swapoff -a → 数据复制进 tmpfs → 校验题目/测点数。
3. 生成名册
CSV(UTF-8 BOM):ticket,name,off_<题目1>,off_<题目2>,...,放到共享目录(如 /media/sf_VMShare/roster.csv)。
4. 判题
# 单进程兜底(学生少或虚拟机不稳时):
bash scripts/vm_run.sh <CONTEST_DIR> /media/sf_VMShare/roster.csv "题目1=1,题目2=3" 0 1
# 双分片并行(正常情况,时间约减半):
bash scripts/vm_run.sh <CONTEST_DIR> /media/sf_VMShare/roster.csv "题目1=1,题目2=3" 0 2
bash scripts/vm_run.sh <CONTEST_DIR> /media/sf_VMShare/roster.csv "题目1=1,题目2=3" 1 2
判定规则(见 judge-rules.md):g++ -O2 -std=c++14;每题逐测试点 1s/512MB;程序必须写 <题目>.out;
比对忽略行末空格与文末空行;得分 = 通过点数/总点数×100。
5. 取结果
结果写客户机本地 /home/vboxuser/jresult_local/results_*.json,每完成一个学生同步到共享目录。
跑完把本地结果/日志拷回共享目录,再拉到 Windows。
6. 出报告
python3 scripts/report_vm.py --roster roster.csv --results results_*.json \
--problems crystal=能量水晶,subway=地铁,migrate=迁徙,hub=研发基地 \
--official-md <官方成绩.md> --out <输出目录>
输出:结果报告.md(含与官方分一致性、只列不一样的差异清单、逐人分数)、逐人明细 CSV。
硬性口径
- 时限逐题核对,不要全用 1s;
LIMIT单位是秒。 - 判题必须用文件 IO(读
<题目>.in写<题目>.out),只写cin/cout的按官方记 0。 - 源文件名必须
<题目>.cpp,.CPP大写按未交 = 0。 - 比对用 CCF 口径(忽略行末空格/文末空行),不要用严格全文比较。
- 提交身份/名单只取官方公示包,别改名、别补造。
常见坑(都是实测踩过的)
| 现象 | 原因 | 处理 |
|---|---|---|
| 虚拟机整机卡死、guest 控制失联 | 判题子进程超时遗孤狂写输出 / 大输入反复磁盘 IO / 8GB 内存不足 | 用 vm_prep.sh 的 tmpfs+swapoff;判题脚本用独立进程组 + killpg + FSIZE/CPU 硬限制;虚拟机加到 12GB/8vCPU |
| 全部判 0 分或全 WA | 比对用了 fulltext_e(少个换行就错)/ 程序没写 .out / 文件名大写 |
用 CCF 口径比对;按官方文件 IO 规则 |
| 判题很慢、某些人卡 10 分钟 | 学生代码贴 1s 时限线 | 属正常边界;可用「每学生总时长保险 + 逐题落盘」防阻塞 |
| 断点续跑 | 虚拟机重启后结果还在 | 脚本按 <ticket>|<题目> 逐题落盘,重启后自动跳过已完成 |
| Windows 调 VBoxManage 参数被改坏 | MSYS 把 /bin/bash 当路径转换 |
命令前加 MSYS_NO_PATHCONV=1(见 vm-ops.md) |