钟知闲IOI2017参赛总结2018-09-28 17:16:20阅读量:5356

 
 

首先,作为中国国家队成员参加IOI2017,我感到十分荣幸。同时十分感谢领队老师们翻译题面,以及老师和同学们对我的帮助和支持。

这次IOI的规则和往年一样,分为两试,每试五小时三题,每题可以多次提交。不过从题型上来说,今年的题型并不像近几年的题那么传统,这一点我在练习赛时也有所意识:练习赛的4题,只有1题是传统题,其余3题则包含了交互题、通信题、提交答案题。

第一试的三题是nowruzwiringtrain,其中nowruz是提交答案题,另外两题是传统题。

第一试我的考场发挥就出了很大问题。首先我看完三题以后,根据往年经验,认为其中一定有简单题,可以很快过掉。于是我把nowruz放一边,先思考wiring的做法,然而一时并没有什么想法。随后我思考train的做法,由于数据范围是n*m复杂度可过的,我猜了一些性质以后设计了一个不会证明正确性的n*m复杂度的DP,经过优化常数之后得到了49分(所有部分分加起来),最后一个subtask答案错误。我想当然地认为算法是对的,是程序实现上的问题,于是花费大量时间调试程序无果,于是过了半场时间我仅有49分。

回头思考wiring,首先写了一个朴素程序提交,过了第一个subtask。然后我在朴素程序上加了个输出方案,通过随机生成较小数据观察方案,不久后发现了DP转移的规律,并且时间可以优化成线性。在我推出正确DP以后还剩1/3场的时间,本来完全能过掉wiring这题的,但我连犯了好几个错误:首先我推的DP方程里有一个数是常量被我误当成变量,于是要写斜率优化,当时感觉可能很难写,而直接用决策单调性的分治法或许很容易写。尽管我没有证明决策单调性是否正确,但我还是花了很长时间编写及调试决策单调性的程序,调到很迟才发现做法是错的。

这时候时间不多,看提交答案题nowruz还没交,赶紧给nowruz的每个测试点随机生成了一个解,得到60分。最后半小时决定打wiring的斜率优化做法,但由于时间不够,最后没有调出来,因此wiring最终仅得30分。

后来和另外几名国家队选手交流,不仅发现wiring被我做复杂了,还发现train我的做法是错的,但由于数据弱多过了一些subtask。当然前面的subtask不难设计出针对性算法解决。

第一试我一共139分,排名40,是一个很糟糕的成绩。wiring这题有大量选手都得到了满分,然而我却因为自己的失误而损失了70分,很痛心。仔细想想,这场我花了太多时间在调自己无法证明的算法上,而明明有靠谱的算法可以写。如果直接就写靠谱算法,不仅能拿到wiring的满分,还能省出时间做nowruz得到更多分。这个成绩我也没有太大的希望拿金牌了,很失落。如果真的是水平不够而没拿到金牌我还能接受,但会做的题却因为这种不应该犯的错而丢了,这就难以接受了。

第二试的三题是prizesimurghbooks,其中prizesimurgh是交互题,books是传统题。

这次我看完三题之后,先开始搞books,通过猜测性质并提交验证,在开场1小时的时候用贪心算法得到50分。拿到分以后开始攻交互题。

prize看完以后注意到题目中一个有用的性质,想到了用分治找出所有候选点验证的算法思路,但细节还是花了好一段时间才处理好,开场不到2小时得到了97分,我的程序在极端数据上询问次数比满分要求多一点。感觉为了几分继续花时间搞很不值得,得到97分就放弃了。

simurgh是一道有关生成树的交互题,经过一些尝试我仍然没能找到高效的算法,只会每次找一个环并确定环上的边是否属于生成树,这样实现得到了51分。之后我试图做出针对完全图的特殊数据,但没有成功。

三题都拿到保底分之后,我决定专攻books。之前的贪心通过了s=0的所有数据,但无法通过s>0的数据,因此我手工模拟了若干组s>0的数据之后发现了问题,意识到需要借助环之间的连通性来解决问题。之后我设计了一个n^2复杂度(且复杂度不满)的DP,拿到70分,最后一个subtask超时。随后我发现这个问题可能可以转成最小树形图来解决,但朱刘算法的复杂度也不能通过最后一个subtask。同时我尝试找出更多的问题性质,依然无果,最后这题70分收场。

第二试我一共218分,排名13。有十余人通过了books,在后来的讨论中我也发现最小树形图也不是正确思路,这题可以转成最短路来解决。当然我的水平差不多就是这个位置了。

两天总分357,排名25,以倒数第二名的成绩拿到了金牌。第一试损失的70分实在太遗憾了,如果多得70分排名就比较靠前了。当然尽管发挥不佳,最后也拿到了金牌,还是挺幸运的吧。

总结这次IOI,和前几年相比的最大特点是非传统题变多了,6道题有3道非传统题,对一些中国选手(尤其是我)不太适应。以及今年难度增大,没有那种送100分的题,选手总体得分偏低,分数线也偏低。值得一提的是提交答案题上次出现已经是5年前的事情了(IOI2012),今年的出现还是让人有些意外。这次IOI对不少选手来说考场策略更为重要,比如往年IOI一般每天有一道容易拿到100分的题,过掉这题以后剩下两题就可以每题花两个多小时研究,但今年IOI如果想先过掉一个题,可能要花很长时间才过掉,甚至还过不掉(比如我尝试过一试的train花了半场结果失败),留给其它题的时间就很少了。以及提交答案题主要考察近似算法,通过大量时间的尝试可以逐步提高得分,但考场上花太多时间会占用其它题的时间;而其它题做太久又会导致没时间尝试提交答案题,所以平衡传统题和提交答案题的时间分配也是不少选手需要考虑的。

以及传统题也和国内比赛有区别,IOI的传统题主要靠分析结论,如果深陷错误结论会浪费大量时间,得到关键结论以后实现并不难。比如一试的wiring我一开始以为n=m时最优解是将第i个红点和第i个蓝点匹配,因而之后基于这个结论的一系列思考全部是错的,所幸不久后发现了这个问题,但推出正解后又陷入了另一错误结论,即决策单调性,调这个错误做法导致我最后时间不够了。IOI允许多次提交的机制对解决结论题有不小的帮助,如二试的books我一开始猜测了一些错误结论,通过提交的反馈发现了结论的问题,最后得到了正确的70分程序。

我这次IOI没取得理想成绩的主要原因是一试考场策略出现问题,花费太多时间在错误算法上。如果我一试采用合适的策略,先每道题拿到保底分而不是鲁莽地认为有一道简单题要先过掉,之后不花大量时间在调试自己都无法证明的错误算法,而是直奔wiring的正确算法,得分就是稳定的,很可能就是另外一种结果了。二试我在拿到三题的保底分之后心态就好了很多,后面books多争取了20分最终惊险得到金牌。然而一试的糟糕成绩依旧是我一个永远的遗憾。

以及就是实力问题,除了一试wiring没看出斜率优化只要用前缀最值即可解决以外,一试的nowruz随机BFS能得到高分,但我没往这个方向尝试;二试的books有十余人满分,我没分析出正解因而没有得到最后30分。

今年中国队是近七年来成绩最差的一次,仅有2个金牌。外国选手的实力不可小觑,今年日本队前5名占了3名,尤其是Yuta Takaya通过了5个题,以极大的优势获得第一名。往年中国队经常都是总分第一,然而今年日本队总分超过了中国队,这也是我们需要反思的地方。相比于IOI的结论题,国内OI模板题和需要复杂算法/数据结构知识的题较多。尽管国内OI很发达,但赛制和题型方面和国际比赛差距还是比较大,当然这几年的命题水平也在进步。总之希望以后中国IOI成绩能恢复到原来的领先地位并保持下去。


最后,尽管我OI退役了,但是在计算机领域OI只是一个开端。这次IOI让我收获了不少经验,是我人生中一项宝贵的财富。