Skip to content

核心概念

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 实现分组独立排名。

→ 详见 标记系统

下一步

你可以继续探索: