2020年是本蒟蒻第一次参加APIO,主要目的是去国赛难度的大赛参观参观 (是学习!不是参观!),而且APIO门槛相对低一些。。。
因此,这篇文章讲的是像我这样的蒟蒻,花完APIO的5个小时的过程。我是蒟蒻,阅读本文不会对您造成碾压伤害,请放心使用~
由于APIO举办时间不同,考生不可以在考试后短时间内传播试题,所以拖了一段时间。其实8月15日当天就写完了。
8月15号9:00到14:00的考试,€€£8月14号下午才发给我账号密码。还好我身边有个群,群里大家说都没有发到,否则真是吓死个人。
8月14号晚上10点,教练那边突然传来消息,说账号密码全部发错了??
早上收到邮件了,CCF他们凌晨三点半发给我的,幸苦了。
然而我的账号和密码并没有变,只是多了国内的账号密码。那么既然CCF说以新的密码为准,那我也不管那么多了。
早上九点,比赛如期举行(我本以为可能会推迟的)。在开始写代码之前,我先花了亿点点时间浏览并理解完了所有问题以及它们所有子任务的要求。我最后才明白我到底要写什么:和平时做到题不同,这些道题要求我写一个函数,评测机会来调用我写的函数,同时传给我输入数据,最后输出函数的返回值。这是我以前从来没有见过的,但是经过了一个半小时的努力,我终于明白了我接下来三个班小时具体要干什么。
第一题(小数据)似乎不难,解开取模运算的外衣,你会发现其实一个请求就是一圈M个承包商转一圈,对应刷你N块墙上M块连续的砖,可以重复刷,但不可以不刷或刷错。
然后问题就变得简单了:考虑贪心思想,假如i块砖之前都涂好了,那这第i块砖我这次不涂,下次还要回来的,那不如就规定我涂完了i-1块砖,下一个请求就必须涂i块。最坏时间复杂度O(N^2 Mlog N )。
还要考虑优化。细节我不方便描述,而且我能力有限,无法描述。。。于是把M优化掉了,最坏O(N^2 log N),期望得分40分,前三个子任务。
我开始写代码了,把它提供给我的库数据下载下来,然后直接在paint.cpp上修改(反正我可以多次下载,不像NOIp,只给你一个压缩包)
代码能力不怎么样的我花一个小时调试后,就陷入了调试的死循环:我的程序先后3次死循环,第一次是样例数据2,调了十几分钟。第二次我把草稿纸上手写的数据拿去测了几次,改了几个数据,又一次成功地卡死了程序,随即找出第二个错:在我的第三给函数返回-1时,第二个函数有时不会返回-1,而会返回0,导致整个程序运行进度后退到0。但是两次调完了之后,提交上去还是0分,第一个子任务就TLE。小数据TLE,显然还是死循环,于是我开始疯狂构造数据。我自己瞎出数据,不知道正确的输出(懒得对拍),只知道要把它卡死就行。有两三次差点放弃,切换页面到第二题去做,但是想想我到现在都还没有分数,花了接近一个半小时的第一题不能放弃,不然这么长时间都白花了。于是我继续随机出数据。
然后我终于意识到不能这样随机出,要出就得出极端的数据,比如所有承包商都喜欢所有种颜色的。我试了试,发现没用。
接下来我又出了一个每个承包商只喜欢一种颜色,然后我刚好想要我的墙壁刷成彩虹色(就是C = [0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3])的情况。最终功夫不负有心人,我终于把我自己卡入死循环了(doge)。
这次问题出在我在做环的时候颜色涂到底就自动回到开头了,这只有满足一定倍数关系才会发生。我之前所有承包商都喜欢所有种颜色没有发现问题,是因为它不符合倍数关系。
又一次提交,这回拿到了40分。看测试点详情,我发现确实和我想的一样,我的程序极不稳定,在小数据有7ms也有112ms,在大数据中我还碰巧对了几个数据点,但由于是捆绑测试,这种骗分方法没有用(正道的光)。
这是已经是12:20了,还剩一百分钟。我开始思考第二题。第二题有两个很诱人的子问题:Q<5和M=N-1,各有30分左右的高分。
Q<5看起来比较简单,因为我看到提第一反应觉得这道题Q<=200000简直没法做。Q<5意味着我每次询问只要在O(N)时间内给出回答即可。
然而十几分钟后我发现我什么也没发现,这种“两辆车不能等在同一点,不能同时经过两条边”的问题我就从来没有遇到过。尤其看到了样例查询(1,2)后就彻底懵逼了:没有限制是简单路径,任何一辆车还可以在某个点停留一会儿,1号车先撤到三号结点,等到二号车过来后再走另一条边回去。最后要求的是经过路线的长度最大值而不是总和…未曾设想的问题!
我本以为就是个路径计数问题,甚至是只要判断是否有多于一条路径即可。
我也想到一个思路,“最大的最小”想到二分答案从而把整张图的权值都去掉。但是我完全没有弄清这个问题的本质:这两辆车要交换位置,到底代表了什么?等价于什么问题?不是等价于简单路径数量>1,因为我也可以在路上找一条小分支避一避,让另一辆车过去。也不是任何路径数量>1,因为你不能通过原地前后摩擦来和它交换位置。题目的文件名是"swap",我觉得这里面有提示,但是我没有得到任何有价值的提示:swap就是交换,你不告诉我我也知道是要交换两辆车的位置,问题是怎么交换?满足什么条件可以交换?
看图:
查询0到2时,两辆车中的一辆可以到4去避一避,从而彼此错开,完成交换。
这张图否定了我大多数的假设。
否定了也好,总比写完了大片代码才发现这个算法是错的好。
我用了三百多个字,配合一张精美的大图,图文并茂地详细解释了为什么我做不出这道题(
之后似乎没过多久,比赛就结束了。
千万不要以为APIO有5个小时3道题,就是有大量空闲的。认真做的童鞋,会发现5个小时其实就一瞬间。(不,我不是第一次知道时间并不充裕,我不是!)
坐我左边的一位选手,看起来比我小两三岁,一直吃东西(5个小时的考试,允许带入水和饮料),就像我第一次参加NOIp一样。
APIO2020结束了,我也没留下什么大遗憾了(第二题我现在想想,也许可以多拿个13分,Q<5并且N<=1000的可以暴力BFS,记录下两辆车各在什么地方)
结束后,听见两个女生在门口讨论:
——“怎么样,有分吗?”
——“没有…哈哈哈哈哈哈哈”
我们信奥班的交流群里,教练也同意:我们只是来学习的,能拿到分就不错了,40分以上的点名表扬/xk
最后,加上一句我们教练的原话: