CSP2020提高组正式赛 比赛总结

15 篇文章 1 订阅
8 篇文章 0 订阅
博主参加了CSP2020提高组正式赛,分享了比赛过程中的时间安排、题目处理和赛后反思。在T1题目中因细节错误丢失大量分数,T2、T3、T4也出现实现问题。赛后意识到代码实现错误和对拍技巧的重要性,提出改进方案。
摘要由CSDN通过智能技术生成

——一句20分的if,一个60分的%d+,两个2.5分的等号和一个炸了65分的人的故事。
这句话官方数据出来以后就没有那么震撼了。
原句:

一句30分的if,一个60分的运算符,两个25分的等号和一个炸了155分的人的故事。

比赛过程

14:30~14:35

监考员在黑板上写了密码,输入了3次才得知某一个写成0的符号是O,再输入了2次才得知前后的括号是密码的内容。

14:35~16:00

点开题目,发现T1是一道看起来很恶心的大模拟题。反正无论如何我都要切掉这道题的,就直接开打了。
先用一个暴力跑出1582年10月4日所对应的儒略日,然后以此为分界点将日期分开。
接着对于1582年10月4日前的日子,直接把公元前4713年1月1日当成0年1月0日来处理,发现这时闰年极其好处理。把天数缩小到4年以内时再把它缩小到1年以内,接着暴力。
最后把小于4713的年份减去4713,大于4713的年份减去4712大概就可以了。

接下来是1582年10月15日以后的日子,一开始想法是先处理1582年10月15日到1584年1月1日(为什么不是1583年,是因为1584年是个闰年,方便后面的处理)的这个区间,再处理1584年1月1日到1600年1月1日这个区间,最后处理1600年以后的年份。
而在年份的处理上,要先缩小到400年以内,再缩小到100年以内,接着是4年、1年,最终锁定日期。细节繁琐,打到16:00时觉得这题要先放一放了,不然后面的题估计都得没分。于是就先做后面的题目了。

16:00~17:30

发现T2是一道真正意义上的签到题。
求出动物一共覆盖了多少个二进制位(记为 x x x),接着答案就等于 2 x − t 2^x -t 2xt,其中 t t t表示 n n n个动物中 2 x − 1 2^x -1 2x1的子集个数。其实 t t t一定是等于 n n n的,但是我当时没有意识到这一点,这也为后来炸了二十几分埋下了伏笔。至于 q q q,完全是没有用的,扔掉就好了。还有可能 x = 64 x=64 x=64,我发现在unsigned long long条件下, 0 − n u m = 2 64 − n u m 0-num=2^{64} -num 0num=264num,因此只用把 a n s = 2 64 ans=2^{64} ans=264的情况特判掉就可以了。

T3只会30分暴力,因此直接线段树模拟就好了。

T4只要考虑一条蛇如果吃掉另一条蛇后,将来会不会被其它蛇吃掉就好了。但是我当时的做法存在问题:比如当前蛇的能力值从高到低是(不考虑相等的情况): a 1 , a 2 , a 3 , ⋯   , a n a_1,a_2,a_3,\cdots ,a_n a1,a2,a3,,an,然后现在1号想要吃掉n号,我就记 a 1 ′ = a 1 − a n a_1'=a_1 -a_n a1=a1an,看这时2会不会把1吃掉……
但是一条蛇被吃掉的条件是它为最后一名啊!!!

17:30~18:00

发现T1可以直接模拟出400年内的年月日,这样就极大地便利了计算的过程。
接着就先把天数缩小到400年以内,再使用预处理出来的结果就好了。

18:00~18:20

T1开始测样例。
很快,小样例全过了。现在只剩下大样例了。
由于不会用cmd或power shell的文件比较命令,我就自己打比较程序。
一开始的打法是先读入所有的数字,再进行比较。但是这样子会把BC前的数字重复读入。
于是改变打法,想要对于每一行,都先分别打开两个文件,再进行比较。然而这样光是打开文件的时间就很大了。
最后想到把每一行读入,然后压缩成一个长长的字符串,再把两个字符串进行比较。接着发现我过了。

但是现在只剩下10分钟了。已经没有时间打对拍了。

18:20~18:30

先完善了考生的txt文件,再检查每一道题目,把 编译选项-代码生成/优化-显示最多警告信息(-Wall) 打开。结果发现T1把long long类型用%d输出了。
改过来之后跑了一下check.exe,接着等了一下比赛就结束了。
出考场时感觉良好,觉得应该有200分,最高是100+100+30+40=270。


赛后

以下的分数都是基于民间数据。

我炸了。
在洛谷上测了一下,T1莫名10分,T2莫名80分,T3、T4竟然都只有25分?!
测了另外的民间数据,T1还是10分,T2变成了75分,T3有30分,T4居然0分了。

这次估计就120左右吧……

检查了一下,T2我在判断二进制数a[i]是否是sum的子集时,是这样子写代码的:

if(choose&a[i]) ...

但是如果 a [ i ] = 0 a[i]=0 a[i]=0我就会挂掉……
应该这样子写:

if((choose&a[i])==a[i])

这两个个等号值25分。

至于T1,错得就更坑了!
我1582年10月4日前的日期错掉了,本该是28 2 4713 BC的我输出了0 3 4713 BC
检查了一下,发现我在确定一年内的日期时,是这样子跑的:

Created with Raphaël 2.3.0 对于一个剩余天数n和当前月份m n≥day[m] 是闰年且m=2 n-=29,++m n-=day[m++] 输出n+1 m year yes no yes no

然后如果是闰年且m=2,n=28,我就会把n减成-1,m加成3。
把这个bug补上就40分了。

接着在后面发现我在访问第m月的天数的数组时,由于下标是从0开始的,因此要把m减去1。
然而我把-打成了+,炸了60分……

于是乎T1就没了90分,这是我最大的失误。因为这并不是方法上的问题,而是实现上的问题;T4那是方法上的问题,倒也没那么严重。


总结

这次比赛主要反映了我以下几点问题:

  1. 先说好的,时间规划上比较合理。在16:00把T1放一放是一个很明智的选择;
  2. 代码实现错误太多了,一些小细节很容易打挂。一定要静下心来,即便某道题很水,代码很短,我很有把握,也要认真地肉眼差错、对拍;
  3. 对拍技巧不行。这次我因为不会用cmd中的fc命令比较文件而失去了二十分钟。平时要多多练习对拍技巧,凡是可以拿到的分都不能丢失!
  4. 平时模拟赛时就极容易写挂代码,这样在考场上毫无疑问是会挂掉的。平时要争取把代码的实现准确度提升。因此,在改题的时候,也要坚持打一段代码就肉眼差错一下,敲完之后再过一过,接着才测样例。

后记

2020.11.16

今天官方数据放了出来,测了一下,40+95+50+20=205。
这个数据很水,有的人T1一堆bug都能拿100,T3暴力就有70了。
虽然我的分数变高了,但是因为大家的分数都增加了,我可能变得更不利。希望能进复赛吧。

2020.11.20

昨天看到了成绩,惊异地发现T1只有20!出题人身后的日期全都没有分了。
一开始以为是数组越界全都没分,但是又不甘放弃加上20分的希望。
据说LOJ上有noi的测试环境,于是交了一下——然后真的就只有20。
后来我又提交了我在gmoj和洛谷上AC的代码,结果只有40分?!!
找了半天,原来是我用%lld输出int类型了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值