京东算法大赛出题人(兼审阅)(兼校对)(兼运维)(兼临时主播)工作报告

这是什么?

今天,京东全国大学生算法设计与编程精英赛决赛结束。对于大部分选手来说,这场比赛题目质量良好,比赛没有出现什么问题。

但比完回到寝室之后,虽然我很困,但决定写一下这玩意。

我是怎么扯到这玩意里面的?

在今年的4月21日,我的一位朋友(下称 A;和我在一个 CS:GO 群里相熟识;具有基本的算法竞赛能力)私聊问我是否愿意出题。其声称他是某个算法竞赛网站的运维,这一机构(以及与其相关的一个数学/OI教育机构)正在承办一场规模比较大、奖金池比较高的 *CPC 赛制比赛。我本人不是一个非常熟练的出题人,但考虑到人际关系,还是同意帮他出一个题。

5月8日,我把题目、标算、数据出好,然后发给了他。题面和题解的格式是 markdown。此时我以为我的活就差不多结束了。此时,A 把我和若干出题人(有些是群友)以及另一个上述机构的组织者 B 拉进了一个群。

在这之间,由于题目数量不够,上述组织者们联系到了某所高校的算法协会,让他们提供一些题目。两位来自于该高校的同学 X, Y 分别提供了一个题目。上述算法协会还联系了一些在该高校预科的高中生进行验题。

5月25日前后,A 需要验题,声称“互相验题是出题人的义务”(之前从来没有提到过),然后要求我们互相验题。显然地,我们都是鸽子,有人时不时地验了几个题。当时题目的质量与细节都参差不齐,比如说举一个数学公式排版的例子:

我尚且不知道什么是 \(log_n^2\),大概是 \(O(\log^2 n)\) 的意思罢!

在这之间,我大概修正了十余处类似于上图的东西,也验了一下某两个题,发现了其中一个题标算的问题。此后几天,另一位出题人发现了我的题目的一些问题:我的编辑器在创建输入输出文件的时候自动采用了 UTF16-LE 格式,在 diff 的时候出现了问题。

然后 A 声称在 6.15 之前我们需要提供每个题的题解的视频,没有说拿来干什么。

然后呢?

京东比赛的海选结束,复赛马上开始。复赛放到了赛氪的OJ上,热身赛非常正常结束了。复赛正式开始之后,(由于我在上课、并且我没有出复赛题)另外一些出题人监控了复赛解题情况。某道比较难的题目中,有两个队伍的代码极其相似,但组织方不知道如何处理。出题群在讨论之后做出了决定,然后写了两封措辞严厉、旁征博引的信,一封发给作弊选手,一封公开给所有选手。后来组织方跑了全量查重,但查重没有发现别的作弊。

在微信群中,某位选手给出了非常致命的一个问题:

啥水平的呀?

当时的我们,还真不知道该怎么回答。

题目怎么样?

(决赛为6月16日。)6月11日,组织者 B 发现题目配置不太行,决定换掉一道决赛的签到题。我们质疑了他的决策,但最终还是真的换了一道题。

我接到通知,比赛当天(6月16日)要去现场。

复赛之后,组织者 A 决定利用 olymp.sty 这一知名算法竞赛题目 \(\LaTeX\) 模板进行题面的排版,但之前我们的题面格式中 Markdown 居多,因此他本人进行了格式的转换。其他出题人没有监督这一过程。

处理完了复赛之后,我们开始准备决赛的题目。6月13日(赛前三天),A 认为需要再加一道题目,然后搞了一道非常简单的签到题。

6月14日(赛前两天)

重叠

此时某道题目的样例是这样的,样例输入长到超出了表格宽度。组织者 A 似乎完全不知道如何解决这一问题。

当天,我们曾多次因为 pdf、题解ppt、题解视频等问题询问 A,其多次咕咕,上线说完了话之后不回复其他人的问题,让我们非常苦恼。

我接到通知,要提前一天(6月15日晚)到达,并且当天要参加一个 20 分钟的直播 session。我碰巧周二晚上没课,可以参加。他们告诉我还有另外三位出题人 X, Y, Z 会来现场。

赛前一天

赛前一天,我早八有课,十点钟英语课有期末 pre,下午一点有太极拳期末考试,三点有电子课的期末堂测。下面的这些事情是我在课程之间的零碎时间抽出来做的。

组织者 B 在私聊中告诉我,选手用机是赞助商提供的笔记本,外接键鼠与显示器。由于赞助商很多,有多款型号不同、配置不同的笔记本,选手之间抽签选出用机;解决不好驱动,他们决定使用 Windows,之后使用虚拟机建立统一的 Linux 环境。当天,B 本人花费了大量的时间熬夜配置了笔记本系统。

当天,我们重新观察了 TeX 排版的题面,才发现有很大的问题。

迫真加粗

这是我自己的题。似乎组织者 A 将 Markdown 直接复制到了 tex 中,并希望它 work。(显然这不 work。)有群友整理了这个版本的 PDF 的某一道题的问题如下:

A题typo

这只是一个题的问题。此时我提议大家使用 overleaf,而不是在 QQ 聊天记录中提出问题。此时,我查看了大量排版问题,有效治疗了低血压,想要看的可以展开下面的折叠。

展开治疗低血压

页面宽度
某个题的问题
itemize了解一下?
表格
基线
你家标点这么值钱?
这个w是什么变量?
你这题输入啥?
\texttt{max}

当日,我从下午三点钟试图修复题面开始,连续在 overleaf 上工作了三个小时到六点左右,终于把格式都差不多变成能看的了。

出发

然后我坐地铁到达了比赛场附近。当天 B 已经在现场处理一些东西,没时间理我,让我先去宾馆入住、然后继续处理题目的东西。

可以看出他也很忙、很困,比我还要 frustrated。因此我尽可能降低了我询问他的频率,使用了尽可能简短的回复。

然后我发现那个版本的 B 题可以在百度上查到

原题

我咨询之后,才知道他们是复用了赛氪之前公开赛的一个题,而这个公开赛由于过于简单,他们不认为场内的选手会做过。我非常无奈,又不能考前一天换题,只能帮他们重写了题意,改了一下故事背景,当然换汤不换药。

然后我稍微休息了一下,帮另一位出题人验了当天的 I 题,和标算拍上了。然后录了我自己的题的题解视频。十二点左右,组织者 B 让我到现场去配置 OJ 与题目数据。

现场

我是比赛当天 1am 第一次到的比赛现场。现在回想起来,我完全不理解一场比赛的出题人为什么要在自己的题目没有问题的情况下在比赛当天的 1am 到 5am 加班。可能是我自己比较愚蠢罢!

他们租了国家会议中心的大宴会厅,现场有 30+ 个建筑人员正在搭建舞台等,有 5+ 个看起来像是设计与管理的人员,舞台上摆好了桌子,然后全场看起来只有两个人理解什么叫做 OJ、什么叫做 SPJ。其中的另一个(组织者 B),正在因为选手用机的摆放而和一个类似于经理/联络人的人 C 争执。

当时的争执是这样子的:C 认为,外接显示器应该放在桌面的侧边,这样不会挡到选手的正脸,能给一个更好的摄像机角度。然后 B 来问我,我对 C 的回答大概是这样的:“我不知道摄像机什么的,我只知道如果选手进来发现这个屏幕在侧边,一定会吐槽然后自己把屏幕移到中间。”

另外一个争吵是滚榜。C 认为,应该要封榜,封完了不公开,只在最后颁奖公布前三。我和 B 都觉得不合理,最后的结论似乎是比赛结束直接就公开最终榜单。

换言之,我到场的时候,基本只有我一个人在处理 OJ 的事情。比赛的承办团队本来应该承担起系统运维的责任,让出题人只需要提交题目就可以了;但此时这个职责空缺了,唯一相关人员(B)需要摆放选手机、搭建舞台,因此沦落到我这个出题人来做数据上传、OJ 测试之类的东西。如果我没有在场,似乎场内就完全没有人来传数据、调试 SPJ 了。我利用 QQ 收到了整个题目的数据包,但这个包里面我自己的题目是不正确的(UTF16 的)历史版本。

版本管理碎碎念

如果有人有做小组大作业的经验,碰巧这个作业还需要做 ppt 或者写论文什么的,并且这个小组还足够活跃、每个人都会改一点,那么一定会遇到版本管理的问题。我已经受够了在微信群里面发送类似于 1.3 - mix - proofread2.0(3).pptx 这样的文件。这样的事情也发生在了本次比赛的组织中。强烈建议所有的小组合作都使用可以追踪历史记录与版本、可以 Review、可以 diff 与合并的工具链,比如收费版 Overleaf、Office + Onedrive、Google Docs、Github、Slack。

我虽然了解过很多 OJ 系统的后台使用,但没有接触过 DOMJudge 的后台;这一后台有非常奇妙的设计,与我熟悉的 OJ 的设计方式完全不同了,我花了一定时间来适应。所幸,github 上有人做了 DOMJudge 版本的 testlib,大大降低了 SPJ 的工作量。我们的评测机也是一台笔记本(虽然我们有真的服务器主机,但笔记本的配置更高,实际上是理智决策),由于内网隔离,我只能通过 U 盘传输数据。最终在 3am,我把数据传完了;4am 左右,我配完了 SPJ,然后跑过了每个题的标算。这是这些题第一次在同一个 OJ 上都跑过一遍。然后果不其然,出现了问题;出题人 X 的防 AK 题标算 runtime-error。此时的我非常困,但不知道该干什么;后来发现是他标算里面前两个数字(\(n, m\))读入反了。修完了之后全部标算都 AC 了,我还写了几个部分正确的测试程序。

就在这个时候,出题人 X 发现这道题的题面也有问题,修完了题面。因此我们的终稿题面是比赛当天 04:50am 才定下来的。在此非常感谢几位出题人能在比赛前一天依然通宵到四点多。

搞完了这些,我立刻回宾馆;天已经亮了。

回程路上

我睡下的时候是 05:10,一夜无梦。

当天

我起床的时候是 10:05。这应当比我这学期其他任何一天的睡眠都短一小时以上。

起床之后我到了现场。所谓的现场,就是大舞台边上一个三个座位宽的小工作桌,只能放三台笔记本电脑;但我们有四个工作人员、四个出题人,因此很多人都没地方坐。

此时他们已经调试好了系统,把其他队伍的信息加上了,正在处理打印的事情。技术人员花了半个小时搞好了比赛期间的打印服务,搞好了打印机;但我们还没有印制试题。于是他们开始打印题目。

在接下来的一个小时中,几位出题人代表也陆陆续续来了。Y 给我带了咖啡,我非常感谢。

打印题目的过程中也出现了很多偏差。首先是主要的那台打印机没墨了,然后是没纸了;导致我们最终需要 48 份,但赛前一小时我们还只有 15 份。我们一度希望跑出去找打印店。后来,主办方联系购买的纸张和墨盒送到了,我们才得以开始打印。打印出来的 48 份试题、接近 800 张纸,是我们在场的几位出题人加上赛氪的两位(我不知晓其职务的)工作人员手工用订书机装订的。

终于打印完了试题之后,已经是赛前 15 分钟了。此时发现还没有打印密码条,而评测机的打印服务出现了一些问题。(是的,他们是在评测机上打印文件的。)他们在某台 mac 电脑上有密码条文件,但需要复制到 linux 上,那台 mac 机只有 type-c 接口,而 hub 坏掉了。我发现我所带的 U 盘是有 type-c 接口的(双口 U 盘),于是借给了他们,终于把密码条打印了出来。我、XYZ 把密码条撕开,但此时直播已经打开了,我们无法上到舞台的机位上放置密码条,于是只能我自己走到舞台另一端、选手上台队伍那里手工分发密码条。此时,组织人员要求我从绝对不能上镜。咨询了主办方之后我们知道,只要直播开着,我们就不能上台,除非穿着他们的 T 恤;并且我们不能使用麦克风,不能广播,只能通过 OJ 中的 Clarification 发送文字广播。

分发的过程中,我发现选手们并不知道这个密码条是什么的密码,然后我告诉他们这是 OJ 的密码。然后我灵机一动,问他们知不知道 OJ 的网址,他们答曰不知道。此时是开赛前五分钟。时间紧迫,我只能在 QQ 里打开聊天记录,里面有一个 IP 地址,然后让每个队记住这个地址

开赛之后,我立刻被叫走去化妆、准备进直播间。直播间中给我的时间预计是 2:05 pm 开始的半小时。在进直播间之前,我私聊询问 B,我在直播间里有什么材料;他完全没有给出任何回答,我甚至不知道直播间里有没有榜(事实上有)。在休息室的我决定自己动手、丰衣足食,于是让 X 拿了一份题面给我。事实上,除了这份题面之外,我确实没有别的纸质资料;直播间内的其他赞助商嘉宾都拿到了一份打印版的题解,但他们似乎觉得我并不需要这种东西。不过由于我是题面的事实上的主要审阅校对者,我对每道题都有一定的熟悉,还是可以讲一些道理出来。我实际上大概 2:10 pm 进直播间,大概呆了 40 分钟左右,其中一部分时间是聊我的题、其他人的题,一部分时间是聊榜单和选手,另外很大一部分时间主要就是听几个赞助商代表在讲故事。自我感觉自己表现的还不错。我还在直播中预言了 top 2,当然地应验了。然后直播结束,他们示意让我离开;但走到房间外面之后,没有任何人来管我要去哪儿(我头上还戴着麦克风),我就问了边上的工作人员,他们说让我找前面的音控。我走到前面音控,才知道他们并没有把我的麦克风关掉,导致我问工作人员的话也被录制到了直播间里面。这算是一个直播事故吧,群里的群友也都提出来了。(为什么他们的音控没有个 mic input channel 的 mixing 呢?不能理解。)

结束之后,我回到了我们的工作桌。我这才知道题面中 J 题的数据范围被删掉了,只能通过 clarification 的方式补回去。然后我出去吃了个饭,回来之后比赛还剩两个小时。

比赛中间倒是没有出什么大问题,只不过需要出题人来分发气球和打印的代码,Y 做了很多这类工作。四小时的比赛三小时封榜也没有出偏差。封榜后打印需求大量增加,有一个队伍不小心把二进制文件传到了打印里面,然后好像某个特定的字符组合会触发换页,因此他们打印的东西连着出了三十多页,我们才通过拔电源的方式把打印机停了。打印机重启之后,由于我们不能麦克风广播,我只能走到每个位置、和每个队伍分别通知“如果之前打印了东西现在还没到,重新打一份”。

比赛结束之后,选手似乎对公开榜单有一些疑惑。我们立刻私下采访了 top 2 队伍,他们反馈说比赛体验良好,但要是多一个小时更好;题目没有遇到太大的问题。我们松了一口气。

赛后

赛后,组织者 A 让我们提供题解视频,然后我们问他题解视频如何公布给选手。然后他说,题解视频不是给选手的,而是放在极值学院上的

我们参加了颁奖典礼,很明显每个队伍都被教育说要感谢三个赞助商,但他们的感谢方法都比较迫真直球。

然后我们就准备走了。由于外面下雨,某大学的几个同学(出题人、选手)决定一起打车;我自己带了伞,带着另一个同学到了地铁站。回到学校东门的时候,地铁坐过站了。然后此时(八点)我还没有吃晚饭,走到学五去买了一碗炸酱面和一倍豆浆。豆浆是热的,学五还没有空调。我满头大汗回到寝室,洗了个澡,然后顶着困倦开始写文章……

小结

下面主要陈列一下各方出现的问题与可能的改进。

  • 首先,这场比赛的时间特殊,可以说是完全不应该出现。有很多选手表明由于比赛时间处在期末季,无法参赛;很多赛事组织人员也因为相关期末事宜,无法进行帮助。我碰巧在周二晚上以及周三没有课,可以说这个比赛的运气非常好了。
  • 作为主办方,在举办一场这样的赛事、选取承办者的过程中,应当对承办者的资质进行评估,应当尽可能考察其承办类似比赛的经验。很明显,本次竞赛实质上进行组织的人缺乏相关经验。
  • 甲方的现场经理对比赛的实质组织者和维护者下了太多的限制。比赛直播,首先得是比赛,然后才是直播,要分清主次;赛前限制我们不能上台、赛中限制我们不能使用麦克风广播,让我们失去了正常比赛的常规工具,使得比赛进程中大量的常规操作需要一个曲折蜿蜒的方法解决,产生了很多障碍。
  • 编程比赛本身观赏性不好,直播的内容只有一半的时间和比赛本身相关,另外一半主要是宣传。我讲的很多东西也非常尴尬,为了上下文连贯性强行给自己的题目变出“现实意义”(虽然这不是第一次了。)
  • 承办/技术支持方的工作人员人手不足、经验不足,导致问题大量扎堆出现,如果没有我这个出题人来解决其中一部分的话,恐怕选手的反馈就不是如此积极的了。注意到这次比赛的奖池较大(前三共 60k 人民币),场地投入较高(国家会议中心大宴会厅),我相信技术支持方拥有足够的预算,原本可以在高校算协等地方找到一个举办比赛经验丰富的人进行组织(或者至少找一个有经验的人来讲讲教训,做做指导),而不是搞成现在的样子,要有我这种不知道从哪里冒出来的外包出题人擦屁股。凌晨在现场的时候,负责修建展台的工作人员在打一个位置难以触及的钉子的时候,说“你别动,让老师傅来打”;这么简单的道理,如果作为一个比赛的承办方还不理解的话,那我也没什么办法。事实上,我认识的相关经验最丰富的人就坐在比赛场里,只不过身份是选手。在赛后和其交流的过程中,其三言两语提供的建议就能解决我们过程中很多的问题(比如,10 道题的比赛应该准备 12 道,以防止出现问题等)。此外,现场的人手明显不足,也是一个很大的问题。我相信其预算应当支持找更多的人来现场做准备。当然,我们也要考虑到比赛处在期末季,让大量可以来协助的同僚无法前来帮助。
  • 作为组织者 A,(我先不谈 tex 之类的技术水平,)须知道这样的出题实际上是依靠个人关系进行联系,如果比赛办的很糟糕的话,事实上是在消费自己的社群地位与友谊。我之所以会去在大晚上不睡觉修锅,一定程度上是出于对其的信任。如果把这种信任当成一种理所应当来作为资源的话,恐怕这种信任就不复存在了。
  • 作为组织者 B,其对组织者 A 以及其他人的职责定位不明,叫我来的时候也没有明确我要干什么,导致后续的责任分配不清楚。就我理解,A 最初的责任只是一个负责联系出题人的角色,而并没有包含其后续的所有工作,因此 A 在自己的工作过程中也出现了明显的混乱。和上面说过的一样,缺人手是一个很大的问题,这在前期准备中也已经出现。
  • 作为出题人,在选择投题目标的时候,也应该对目标进行一定的资质审核。

某一次比赛不出现问题,不代表下一次也不会。如果我这个格式警察、OJ 运维没有出现的话,这场比赛留给选手的体验如何,也没人知道。但我已经知道明年该比赛会继续办下去,至于明年这比赛办的怎样,我们可以拭目以待。

最后,我们引用一段来自Dai@NeverLand, 知乎论及 2019 年银川区域赛时的话来结尾:

『到底在竞赛环境不好的情况下,做很多工作去「救」比赛,对比赛是好还是坏?』

由于时代比较久远,我不是特别记得具体细节了,依稀记得朱老师的观点是『应该彻底不管,让比赛彻底重生,才有可能变好』,我则觉得该救还是要救的,也没那么不堪。

没想到啊,好像还没到两年,现实就狠狠的打了我的脸。救么,还是有人救的,毕竟国内哪没有人呢?不过现实的情况就是情况一年比一年更差了。

我无意对『救』发表什么意见,毕竟每个人有自己的看法和选择,救火队员受到鼓励和支持,应该,也合理。

只不过『救』的了一场比赛,『救』的了一年比一年更差的环境吗?低价甚至无偿的出题、做技术、擦屁股,真的可以掩盖组织方毫无经验也不思进取,不直面事故,不沟通,对公平性毫无概念的事实吗?真的可以掩盖背后推手们各打着自己的如意小算盘,以竞赛之名行沽名钓誉之实吗?不大能吧。

说实在话,蛮遗憾的。倒也不是遗憾别的,就是有些遗憾,总有人喜欢利用竞赛选手的好心肠。可悲可叹。

题解

我们现在没有整理好全部题解。如果需要题解的选手,请发送电子邮件到 noreply at pku.edu.cn,我们会在题解打包好了之后回复你的邮件。