关于新生赛的反思总结

  本文最初成稿于2019年12月15日,发布后历经数次改动,但在2021年1月23日的博客框架更换中不幸被遗失。近日碰巧在提交记录中发现,因此重新发布。
——写于2025年1月9日

  新生赛终于结束啦~

前言

  于2019年11月24日在上海大学举办的 ICPC Regional 中,我校以一银一铜两铁惨淡收场。于我个人而言,这场比赛宣告着曾经作为ICPC选手的我正式退役。根据之前的规划,整个大三下与大四上的时间都将被分配给考研,为此我已经推掉了几乎所有之后的比赛,ICPC当然也不例外。

  回顾这两年的参赛经历,最好的成绩也仅仅是在去年的上海大都会赛拿了铜牌而已,参加的过两次区域赛都以打铁告终。比赛结束后,队友问我,“如果就这样结束,你不感到遗憾吗?”我没有立刻回答他。诚然,我们都为这个比赛付出了许多努力,也都为这样的结果而感到不甘。但竞赛毕竟只是大学生活的一个组成部分,在竞赛上获得成就相对于获得更高的学历来说更像是一个阶段性目标。若是为了挽救阶段性目标的失败而打乱了全局的规划,从长远来看必然是得不偿失的。因此,在和队友们开诚布公地交流过后,队友们表示能够理解我的想法,也接受了我离队退役转而开始备战考研的选择。

  尽管名义上已经算是正式退役,但我在机房的故事并没有就此结束。由于我校今年缺经费主动放弃了EC-Final的参赛资格,所以事实上已经结束了这一赛季的主要赛事。集训队的老队员们也都暂时闲了下来。与此同时,今年机房里也多了几位常驻同学,包括19级的JZW、LTY和YST。大家都期待着一次证明自己的机会。因此,在正式退役的数日之后,我联合几位集训队老队员与社团骨干,联系L教练启动了本年度校新生赛的筹备工作,也算是在退役之后再为集训队的发展做点微小的贡献。

开始筹备

  “新生赛没有钱。”这是我联系教练时最初得到的回复。

  没有钱要怎么办比赛?其实从去年第一次组织新生赛时我就在思考这个问题。

  一场典型的程序设计竞赛有着较为复杂的流程。首先是命题工作,其次是比赛赛场的设备与环境的配置,接着是比赛相关物资的准备,再之后就是比赛当日的控场与负责气球发放、维护比赛秩序的志愿者以及裁判的到场。最后还需要关注相关的宣传工作,主要包括赛前宣传、赛时的摄影与赛后的总结。

  逐个分析一下每个环节里赞助费这一角色的替代方案:

  首先是命题工作。命题可以说是程序设计竞赛最关键也最重要的环节。整个比赛可以说是命题人(裁判组)意志的展现:需要多少道题目?需要给多少时间?每道题目的考察点与易错点是什么?选手做完整场比赛的所有题目后能得到什么收获?许多诸如此类的问题实际是需要命题人来自问自答的。在这一环节里,赞助费的主要作用是作为命题人的酬劳。而替代方案也很容易想到:把命题工作作为集训队队内互测的组成部分,并向老队员们征集题目与出题思路。这个方案的实施过程可谓非常成功。一听到要征集新生赛的题目,各位老队员都感到很兴奋,大家都热心地掏出自己攒了一整年的鬼点子想要放到新生赛的题目里。但作为整个比赛的负责人,我还是尽力劝说大家尽量克制,出题时尽量要以对新生的基本能力与基础知识进行考察作为主要目的。

  其次是比赛赛场的设备与环境的配置。新生赛创立时最初的目的之一就是让新生们提前体验正式比赛的感觉,为此比赛的设备与开发环境都应该朝着ICPC的标准靠拢。但由于各种限制,目前来说新生赛的实际规则更接近于CodeForces上的个人参赛规则。因此,现阶段的新生赛是完全可以在学院信息楼的百人机房内完成的。恰好,去年我通过某些途径结识了在运维方面有着深入见解与独特洞察力的YHL同学(非集训队成员),在他的协助下我和集训队老队员DRU对学校、机房的网络环境以及Linux系统的理解和认知都提高了一个层次。在这一环节里,赞助费的主要作用是作为环境配置工作人员的酬劳。我们的替代方案主要是,通过将勤工助学指导中心拉拢来作为协办方,给予了他们提供运维方面技术协助的责任。这其实并不是一个非常好的替代方案,因为事情能谈成主要还是因为先前有社团和指导中心的合作协议的存在。另外,在机房比赛环境配置的过程中,机房的WYB老师也为我们提供了相当大的帮助。

  接着是比赛相关物资的准备。所幸去年新生赛与今年的上海市邀请赛筹备时使用经费购买的气球、透明胶带什么的耗材都还有一定的存留,整理并清点完成后发现完全可以支持一个百人规模比赛的正常运作。而A4纸和笔这类非必要也没有留下储备的耗材只能放弃了。因此,这一环节的赞助费的替代方案就是使用之前有赞助的比赛余下的物资。这个方案从长远来看也是有效的:我校承办上海市邀请赛的时候可以拉到还算充足的赞助费,在这个时候多买一些耗材以供之后的校内赛使用实际上是利用了摊还的思想。

  再之后就是比赛当日的控场与负责气球发放、维护比赛秩序的志愿者的聘请其实是相对来说比较麻烦的一步。招募志愿者理应提供补贴,或者最起码提供餐补,但由于实在是没有经费,我们能提供的只有志愿时长。因此我们使用的替代方案是声称这次活动的性质属于社内活动,并据此呼吁社员们尽量参加。协办方社团CIC社也为本次比赛做出了许多贡献。

  至此,需要考虑的就只有一些宣传工作了。宣传主要是承办方的职责,而在承办方的两大主体也即社团和学院学生会之间,社团已经有了相当多需要负责的工作,因此宣传工作的重点自然也落到了学生会的身上。在这一阶段,赞助经费主要用于各种宣传材料的制作费用。对于赞助经费的替代方案,我其实没有想到什么好的方法,因此在实际操作过程中由我个人先行垫付。不过还好,总体来说花费并不太多。

  总之,综上所述,即使在完全没有经费的情况下,我们也能东拼西凑地基本完成整个比赛的筹备与举办工作。因此,我向教练据理力争,争取到了举办本次新生赛的机会。当晚,我就联系众人成立了“2019年校新生程序设计竞赛组委会”。主要成员有:顾问CSH、顾问DRU、顾问YHL、环境组负责人SYF、志愿组负责人WXY、裁判组负责人LZH、宣传组负责人XYB。

  本次比赛的筹备时间其实满打满算只有两周而已,我个人觉得这么短的时间其实并来不及把所有工作都做到比较好的状态,后来事实证明也确实是这样,很多本该测试的环节与内容我们都没有机会Cover到。在比赛的举办时间上,我曾和L教练进行了短暂的拉锯,但由于考虑到学校的教学安排计划,最后还是无奈接受了在第十五周周末进行承办这个对赛事筹备来说压力比较大的方案。

关于海报

  在我的要求下,我参与了海报设计的审查阶段。在审查的过程中可以明显感觉到,参与工作的新生同学们对于“设计的元素要尽可能的服务于设计意图”这一基本原理缺乏着理解与认同,因此原稿上存在着很多意义不明的设计元素。我和学弟一起对原稿进行了大刀阔斧的重构,加入了使用Wordcloud库生成的中央词云,并使得设计的结构在总体上与去年的海报相似,随后去除了很多与设计意图并不直接相关的元素。(第一张为原稿,第二张为修改后的终稿)


  海报在制作完成后,本来想挂在篮球场围栏的铁丝网上,却遇到了意料之外的问题。尽管我们准备齐了所有文件里提到的应该附上的材料,但还是在审核的过程中莫名其妙地被校团委以“材料不全”的名义否决掉了。我们联系了兄弟社团后,发现他们也曾遇到过这样的事情,而且申诉起来十分困难。从头再走一遍申诉流程肯定来不及了,于是当晚我联系了L教练,询问是否由把喷绘海报直接挂在学院信息楼的可能。在L教练确定没有问题后,第二日我们就把喷绘挂了上去。从结果来看,受海风摧残而止不住摇摆的海报显然完全发挥出了它的价值,吸引了许多师生的关注。

关于题目

  题目的准备过程主要由LZH负责监督。这里只是单单描述一下我了解到的内容,很可能并不全面。在确定准备开始承办本年度的新生赛之前,ZYH同学就拿着一道题目来问我DOMJUDGE是否支持卡内存。但我们实测下来,对Java程序进行内存限制会导致非稳定的结果,包括测评程序的崩溃与内部错误等。因此,后来他的题目没有能够成为正式比赛的一部分。之后,FCY同学也找来了一道他之前出过的觉得质量还行但没有向校内同学作为例题讲解过的题目。SYF同学提供了四道热身赛的题目(似乎是对某几场CF的原题进行了翻译与魔改)。后来,在我的建议下,热身赛的最后一题被放入了正式赛。另外,PBO同学提供了两道自己想到的题目,而LZH同学则花费了大量时间和经历给出了正式赛剩下的五道题目。因此,比赛最后的实际情况是,热身赛两小时三题,正式赛三小时八题。在筹备题目期间,主要是PBO、LZH和SYF三位同学之间互相对题目的正确性进行了交叉验证。

最后,这里引述一下命题组负责人LZH同学对于命题工作的反思与总结以供参考:

  • 比赛前考虑到参赛选手水平差距很大,且大部分水平不高,如何让高水平选手和普通选手都享受比赛是我组织题目的主要宗旨。一开始,我收到了PBO同学两道冗长的题目,心里有点发毛,但还是放了(事实证明不太明智)。随后,又收到FCY同学的两道题目,感觉难度合适且代码量不大。可惜的是ZYH同学的奇妙题目由于数据和评测环境的问题被我拒掉。到了这个时候,我开始考虑自己补充题目,出了一个题面更冗长的博弈论。
  • 在比赛临近的时候,感觉题目难度梯度断档太明显而且我的题八成没人做,于是果断删掉我的博弈论,搬运修改了一个二分+dfs,这样做增加了考察的知识面,平滑了难度梯度。
  • 在比赛更加临近的时候,觉得把PBO同学的题作为签到有点残忍,而且感觉大多数选手会陷入无题可做的境地,于是加到8题,补了一个真签到和一个数学规律题。
  • 事实证明这套题对于新生赛还是非常合适的,可惜最大的缺点就是对高水平选手区分度不够。
  • 比赛过程中,在初期选手们过题比较顺利,之后很多人卡到A题或D题,卡到A题很多是因为题目描述有一点歧义,卡到D题那是实力不够。我们考虑之后发了Clarification,有点效果(但是感觉很多选手还是没有看)。最终大多选手卡在3题,可能因为A题耗了太多时间,相信如果延长时间还是会有很多选手过456题的。
  • 比赛结束以后,总体来看对题目比较满意,题目对新生代码能力和思维能力区分度良好。

关于环境

  由于我今年已经退休成为了顾问,比赛环境的配置与测试工作实际上是主要由SYF同学完成的。相对于PC^2,DOMJUDGE要更加复杂一些,具体体现在需要安装并配置PHP、MYSQL等额外的环境上,同时我们还尝试着配置了ICPC Tools和CDS等工具用于统计气球的分发记录。和去年类似,我们还是采用了桌号-账户-选手这一映射关系来确认气球分发具体位置。在比赛正式开始之前,所有的工具都测试成功了,但比赛当日CDS似乎由于链接数过载而失去响应因而无法使用(仅40名选手)。具体的错误日志还在需要进一步分析研究。

  关于选手机,一开始我们打算使用ICPC WF2019的官方镜像,但由于官方镜像版本较新,无法适应机房电脑的集成显卡而会导致开机卡死等问题,在多次尝试修复未果后经过取舍决定重新使用去年上海市邀请赛时安装的Manjaro系统。对于裁判机和比赛服务器,我们刷入了我个人相对更加熟悉的LUbuntu系统。经过尝试后,我们发现DOMJUDGE与ICPC Tools之间的协作其实并不十分稳定,这也许会成为未来环境配置上将会遇到的问题。不过就目前而言还勉强能够接受。

  对于网络环境的隔离,我们采用了双网卡的方案:比赛服务器使用一个额外的无线网卡,通过无线网络将比赛的榜单转发到校园网网络里,使得校园网内网的用户都能访问到榜单;而比赛环境内选手机使用的有线网络则被物理上与外网断开连接,保证了比赛的公平性。

  另外,在环境搭建上,今年我们犯了一个严重的错误,险些导致比赛无法进行。在分发完选手机前,我们未对原有网络设置进行复原(自动IP配置脚本需要这一步骤),因此分发完成的机器的网络设置全部都没有成功生效。但分发完成后,我们并没有考虑到这一点,直到比赛当日才发现了这个问题。最后,由当时在场的顾问DRU带着志愿者手动把网络的问题给解决了。这个问题的责任在我,也在于我们没有在比赛前对分发完成的选手机进行测试。

  还有一件值得一提的事情:在比赛正式开赛前,SYF同学发现题目的数据有误,因此试图重新导入,却发现被拒绝并提示了“主键冲突”错误。经验还不是很足的他并没有立刻反应过来问题的所在,当时也并没有想到可行的解法,因而慌乱之下清空了数据库并重新开始从头配置比赛,完成了半次真实的“删库跑路”操作。由于这一不规范的操作,CDS上的气球服务缓存数据与数据库产生了不同步,因而开始频繁保报错,后来无奈只能取消掉CDS服务器。所幸这一行为并没有对比赛产生其他重大影响。当然,事后我也找出了一本“数据库原理”教材送给了自称“睡了一觉后突然理解了问题所在并明白了正确的处理手段”的SYF同学。

尾声

  伴随着新生赛的收尾工作,我大学两年多的竞赛生涯也基本算是真正的结束了。赛后,我问到开赛后两个半小时AK离场的JZW巨佬对本次比赛的感受时,他答道:“挺好的,体验还不错。”我相信这样的回答对全体新生赛的相关工作人员来说都是最好的慰藉与激励。这意味着,尽管整个比赛过程问题频发,我们还是成功地保证了比赛的公正与秩序。我相信,在积累了这次筹备比赛的经验之后,未来学弟学妹们会把新生赛办得越来越好。