---
# System prepended metadata

title: '[周末休闲赛抽奖算法说明文档](https://hackmd.io/@baobaobear/rkBkO9sO_)'
tags: [说明]

---

---
tags: 说明
---

# [周末休闲赛抽奖算法说明文档](https://hackmd.io/@baobaobear/rkBkO9sO_)

本文档为20210707版

## 定义1：有效提交

对于同一个用户，同一个题，在第一次AC提交及其之前的提交，只要已有返回结果，那么都属于有效提交。而在第一次AC提交之后，所有的提交均为无效提交，不参与计算。

## 定义2：最后一个AC

在比赛结束前，所有的有效提交里面，提交时间最晚的一个，且结果为AC。

## 定义3：总AC数

在比赛结束前，所有有效提交的AC总数。公式里使用 $N$ 表示。

## 定义4：有效参与比赛

在比赛结束前，得分大于 $0$ 的人。

## 定义5：参与人数

有效参与比赛的总人数为参与人数。公式里使用 $P$ 表示。

## 定义6：抽奖人数

抽奖比例为一个大于 $0$ 小于 $1$ 的常数，计算参与人数乘以抽奖比例的下取整，为抽奖人数。公式里使用M表示。若抽奖比例为 $0.6$，那么有

$$M=\lfloor P \times 0.6\rfloor$$

## 定义7：提交时间

某个提交转换为 $Unix$ 时间戳，是一个精度为秒的整数。而最后一个AC的提交时间公式里使用 $A$ 表示。

## 定义8：常数C

$C$ 定义为 $0$ 到 $2^{64}-1$ 之间的整数，此数值在比赛结束前不公布，由Baobaobear随机选取，比赛开始期间这个常数不会变化，结束后公布。此数值的 $10$ 进制表示的字符串的 $SHA1$ 值会公布在VJudge的比赛描述里（主页面的最底下）。

## 定义9：计算公式

$$f(x)=(6364136223846793005 \times x) \ mod \ 2^{64}$$

$$Rank = (A + f(N + C))\ mod \ M + 1$$

$Rank$ 为中奖者的排名，排名从 $1$ 开始，所以公式中最后需要加 $1$。

排名方法由VJudge里设定的排名规则决定。

## 其它情况

对于参与人数小于4的情况，不进行抽奖。如果中奖者无法联系导致奖品无法发出的情况，视其为放弃奖品，那么对公式中的 $N$ 加上1再代入公式计算新的中奖者。如以上情况仍然发生，那么奖品累积到下一场比赛。
