这次模拟赛自认为发挥得还可以,最起码该拿到的分数最后都拿到了。
但是,我说了“最后”,就说明比赛过程其实还是不尽人意的。
首先是略读各题大意,大概花了几分钟。发现 T4 是纯净水,T5 是刚做的单调队列练习之一,马上交了这两题,都是 1A。此时比赛开始 15min。
静下心来想,前两题不知道怎么保证括号序列的合法性。暂时没有思路所以只能去看 T3。
感觉 T3 的 40% 部分分应该不难拿,细细分析一下的确可行,花了 5min 梳理大致流程和一些细节,之后马上花 10min 打了个简单粗暴的暴力。
交上去是 50 分,估计可能写得常数比较小,可以多卡过一个点。此时比赛开始 30min。
现在面临两个选择,要么回去推 T1、T2,要么在这个暴力的基础上好好想正解。决定选择了后者。事后看来这个决策应该是明智的。
于是分析暴力中可以优化的地方,想到了用二分确定最远能控制自己的点,这是很关键的一个跨越。
但是只是有了大体思路,具体怎么二分又懵了。灵光乍现,突然想起有种叫倍增的东西,然后发现自己好像忘了,但大体的思想还记得。
于是开始现场手推,终于推出来了。然后开始写代码,结果有个地方没想清楚,回去草稿纸上面重推一遍发现变量的含义弄错了,修改了一下感觉没问题。
从开始想正解到写完代码前后总共花了 1h 左右。跑样例,过了。交了之后爆零。(反思:这里为什么没有先自己出几组小数据本地跑一跑?)
先是肉眼查错,但是读代码的时候以为都是符合自己考虑的逻辑的,就跳跃着读。然后就忽略了我在另外一个地方用了被修改的变量,然而忘记随之修改了。
于是只好单步,到最后发现没有把原来的 sum[par[cur][mid]]
改成 sum[mid]
了。这就是因为一开始没有考虑清楚,后面改了变量含义忘记修改使用的地方。
改好了之后再交,A 了。此时比赛开始 2h。(反思:对变量含义的考虑应该在正式开始写代码之前就想好,中途修改一定要注意把所有涉及该量的地方都改)
再比较 T1 和 T2,觉得 T1 会好推一些,就先去推 T1。
整整推了大概 1.5h,都在为括号序列合法性的判断纠结,最后在一堆模拟和观察中发现通过左括号个数总是大于等于右括号个数的性质,但不知道怎么利用。
于是就想 T2 虽然看起来更难,但 O(2m) 的暴力会很好写。暂时放下 T1 去打 T2 的暴力。
我也担心过会太暴力,拿不到分。但又感觉拿到 T2 暴力分之后就可以安心推 T1 了,那就写吧。
打了大概 20min,样例过了。这时候吸取 T3 的教训,构造了几组小数据,都跟手算结果一致。交了之后 20 分,有两个点是 WA 而不是 TLE。
暴力也会 WA?
肉眼查错 2min,怀疑是自己定义的无穷大不够大,于是扩大了几倍,但是保证在一个安全范围内,不会导致溢出的可能。再交还是 20。
似乎实在找不到什么地方修改,又不想浪费时间,于是只好推回去 T1 的 DP 了。(反思:比赛一结束马上发现自己多组数据忘记初始化了,低级错误!!!)
推了大概 20min,弄出了一个奇怪的四维状态,然而感觉还是挺正确的,写代码。跑样例,过了。
这时候才从转移部分的代码上发现,左右括号的处理貌似其实是一致的。然而感觉不需要再优化也可以过,就交了。
结果只得了 11 分,其他全部 WA。百思不得其解,样例中的第五组询问那么大都对了,怎么可能还会 WA 呢?也不太可能是溢出了,我都开了 long long 了。
但是又想到答案可能确实会很大,回去看题面,发现要 % 107+7 ,我竟然忽略了。(反思:读题不认真!)
改了重交,居然还是 11 分。怀疑可能是决策部分先加完两种可能性再来模的时候爆了,于是再改成每加完一遍就马上模一遍。
再交,居然还是 11 分。发现转移部分
i
的取值从 0 开始,取 if (i > 0)
……
再交,还是 11 分!我都要崩溃了。但是静下心来,既然算法应该是没有错的(样例里面有组答案较大的都算对了),那么必然是细节问题。
一行一行读,一个变量一个变量排查……每读到一个量就问自己,它代表什么含义?特别是数组,下标的上限是多少?
读到
f[i][j][k][0/1]
的时候就想,
i
嘛,无非最多是 50,
好像发现了新大陆一样,再回去看定义部分:f[MAXL][MAXL][MAXL][5],而且 MAXL 我就开了 50。
马上把第三维开大一倍,跑样例,过。交,终于 A 了。因为这个数组开小,前前后后花了我 10min,在比赛结束前 5min 才 A 掉这题。
纵观这个比赛过程,前半部分还算正常发挥,后半部分就比较惨了。总的来说有几个问题:
有 40 分其实是应该拿而没拿到的(T2 的 DP,事后再来看其实也并不难想)。
推 T1 的 DP 花了太多时间,可能是做的 DP 题不够多,没有想到通过对状态自身的含义进行规定,从而满足一定的限制,但好在最后也 A 了。
细节的地方出错太多,如果是正式 OI 比赛这样就很可惜了。就算最后查出了错,改正了过来,也会浪费很多不必要的时间。
所以还是应该要先思考清楚再开始打代码,打的时候要谨慎一些,尽可能避免修改和调试。多练习,多反思,才能有所提高。