核心概念
srk 是静态榜单数据格式。也即:它是一份可以完整描述榜单在某个时间点的快照的数据格式。而不是只记录分离的「提交记录」「参赛者」「题目」等数据再交给工具动态计算的传统组织方式。
这个设计的好处经过了长期实践验证,除了天然免计算、易于解析和展示外,「快照」的设计哲学从一开始便能兼容来自 HTML 存档、PDF 或截图等形式的数据源转换,以及不完整的榜单数据(如缺失具体提交记录,只有分数的数据),它几乎没有适用场景的限制。
借助实用工具,我们还能轻松地将静态榜单转换为传统的「基于时间序列的提交列表」形式,方便进行增量更新和高性能计算(事实上,srk 官方工具链就是这样处理动态插入和重排的)。
接下来,让我们开始窥探 srk 数据结构,这将帮助你在深入各个模块之前建立起整体认知。
顶层结构
一份 srk 文档是一个 JSON 对象(称为 Ranklist),包含以下核心字段:
json
{
"type": "general",
"version": "0.3.12",
"contest": { ... },
"problems": [ ... ],
"series": [ ... ],
"rows": [ ... ],
"markers": [ ... ],
"sorter": { ... }
}| 字段 | 说明 | 必填 |
|---|---|---|
type | 格式类型,当前固定为 "general" | ✅ |
version | 规范版本号 | ✅ |
contest | 比赛基本信息(标题、时间等) | ✅ |
problems | 题目列表 | ✅ |
rows | 行数据(排名行) | ✅ |
series | 排名系列配置 | ✅ |
markers | 参赛者分组标记配置 | ❌ |
sorter | 排序算法配置 | ❌ |
以下图例展示了各核心对象之间的关系:
Ranklist
├── contest ─────────── 比赛信息(标题、开始时间、持续时间……)
├── problems[] ──────── 题目列表
│ └── Problem ─────── 单个题目(别名、标题、统计……)
├── rows[] ──────────── 排名行(核心数据,每位参赛者对应一行)
│ ├── user ────────── 参赛者(选手/队伍)信息
│ ├── score ───────── 得分
│ └── statuses[] ──── 每道题的状态(与 problems[] 一一对应)
│ ├── result ──── 结果(AC/RJ/FB/...)
│ ├── tries ───── 尝试次数
│ └── solutions[] 提交记录
├── series[] ────────── 排名系列
│ ├── segments[] ──── 奖区分段配置
│ └── rule ────────── 排名计算规则
├── markers[] ───────── 参赛者标记配置
│ └── Marker ──────── 单个标记(ID、标签、样式)
└── sorter ──────────── 排序算法(ICPC / score)核心对象速览
Contest(比赛信息)
描述比赛的基本信息:标题、开始时间、持续时间、封榜时间等。
→ 详见 比赛信息与题目
Problem(题目)
描述单个题目:别名(如 A、B、C)、标题、链接、提交统计等。
→ 详见 比赛信息与题目
User(参赛者)
描述一个参赛者:ID、名称、所属组织、是否正式参赛、队伍成员等。
→ 详见 参赛者
RanklistRow(排名行)
一行排名数据,包含参赛者信息、总分,以及每道题的状态。
→ 详见 排名行
RankSeries(排名系列)
定义一个排名维度,如「总排名」「学校排名」「地区排名」等。每个系列可以有自己的奖牌分配规则。
→ 详见 排名系列与奖区
Sorter(排序器)
定义排名的排序算法(如 ICPC 规则或纯分数排序)。
→ 详见 排序算法
Marker(标记)
用于给参赛者额外添加元数据标记(如女队、省内队伍),可配合 Series 实现分组独立排名。
→ 详见 标记系统
下一步
你可以继续探索: