这次比赛赛前,有消息称这次比赛的难度是div1,比赛前心里没底。因为自己的学校实力不强,所以这次现场赛资格也来之不易,这是我第一次也是我最后一次打ICPC,所以我不想留下遗憾。
拿到题目的时候也有点畏惧,因为这次比赛的题目都很长,而且是全英文的。为了防止漫无目的的读题而影响做题时间,我们决定跟榜。很快有大佬队过了J题,J题题面有整整一面,硬着头皮上吧。很快读完题就发现,这题是个模拟题。
给出一行C语言语句,求声明变量所占用的字节数,声明的变量或者数组只能有一个。
直接暴力即可。
由于不熟悉Linux操作系统下的编程环境,队友在写这个程序的时候也遇到了一些问题,比如字符串输入没有gets和getline函数(编译器是真的卡),无奈,只能用getchar进行输入了。写程序的速度还算快,草草写完测了几组样例,感觉没问题就提交了,结果不尽如人意,Wrong Answer。然后我们马上找到了一组错误样例,改了程序,重新测试了几组样例,这次应该没问题了,提交上去还是Wrong Answer,心态瞬间崩了。我说干脆直接用%s输入吧,对于变量类型直接判断首字母就行了,long long和long double另作判断。然后队友又重新写了份代码,跑了先前测试的样例,然后提交上去,随后我们就看到了correct原谅色的反馈结果,心态终于正了正。此时我们不敢看排名,因为有两次罚时,名次肯定在老远。
时间已过去将近一个小时。有大佬队开了C题,我们马上转战C题。在读懂题意之后,我们感觉这就是个规律题。
现有一段函数,要求输入一个数组A和一个k,进行一次题目给出的冒泡排序(题目名叫插入排序,过程是冒泡。。),进行k次。
题目的意思是,给你三个数,n,k,mod,问你在1-n的全排列中,有多少个序列运行这个函数之后其最长上升子序列的长度大于等于(n-1),最后的结果对mod取模。1<=n,k<=50,1e8<=mod<=1e9。 给出题目中的程序
function Insertionsort(A,k) n←the length of A i←1 while i<=n and i<=k do j←i while j>1 and A[j-1]>A[j] do t←A[j] A[j]←A[j-1] A[j-1]←t j←j-1 end while i←i+1 end while end function样例给的是4 1,4 2,4 3,4 4(省略mod)的,note也比较贴心,把4 1的情况的排列全部列举出来了,观察了一番,并没有找到什么规律。果断写全排列和LIS暴力一下,由于10的全排列就很多了,所以我们打了1 1到8 8表,这一列出来我就发现了规律。分别以n和k为两维,构建了一个矩阵。
1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 5 6 6 6 6 6 6 6 10 14 24 24 24 24 24 24 17 26 54 120 120 120 120 120 26 42 96 264 720 720 720 720 37 62 150 456 1560 5040 5040 5040 50 86 216 696 2640 10800 40320 40320纵坐标是n,横坐标是k。
很明显就能看出当n>=k的时候,结果全为n!。对于k>=n这种情况,直接输出n!。然后我们讨论剩下的情况,对于每一列我们求出差分序列。
1 3 4 5 8 18 7 12 30 96 9 16 42 144 600 11 20 54 192 840 4320 13 24 66 240 1080 5760 35280对于每一列,差分序列构成了一个等差数列,哇!当时我发现这个规律的时候是真的开心。然后我又发现,对于每个序列的,其首项是i * i!,然后差是2 * i!,验证:对于第四列,96 144 192 240,96=4 * 4!,144-96=2 * 4!。由于这个这个题的n和k很小,但是数值很大,而且模数不定,不能一开始就把所有结果打表。我们可以先找出(n,k)这种情况,然后递推下去,直到求出答案。
代码写的飞快,样例测了也没问题,就直接提交了。本以为这题应该能1A,可是又反回了Runtime Error,当时真的是眼前一黑,哪里越界了?鼓起勇气看了下排名,已经掉到100+了,凉凉。突然队友说了句,woc!输入还有个t,然后加了个t的输入,光速提交,本以为这次稳了,结果又是Wrong Answer。规律错了?规律错了?规律错了?我规律找错了?我问,题目中有没有n<k这种情况?队友又说,woc!我没写n<k这种情况!然后他加上这种情况后,提交上去,Correct!看一眼rank,我们到43名了,但是在两题尾,,离比赛结束还有三小时,继续开题。
随后看到了G题,感觉能写,题目给了12s的限时。
在一个二维空间内,开始给出n个点,和每个点的w值,接下来有m个操作,一共有四种操作,增删改查。然后让输出给次查询结果。查询的时候会给出一个k值和(x,y),如果有点跟他的欧几里得距离等于sqrt(k),那么就加上其w值,最后输出和。对于每次操作有个lastans,真正的坐标是(((x+lastans)`00+1),((y+lastans)`00+1))。0<=k<=1e7,1<=x,y,w<=6000,1<=n,m<=1e5。
由于0<=k<=1e7,所以我们可以完全可以把1-1e7所有平方数和拆分出来。也没有多少,最多才3000多。然后就直接暴力,这样复杂度是大概有1e8,12s限时。
按照这种思路,我们写了程序,交上去就TLE了,一直怀疑是方法错了,然后就一直在尝试这一题直到比赛结束。后来问了北航的大佬,他们也是这样写的,但是他们在维护整个图的状态的时候,用的是map!我透!因为这题有1e5的操作数,STL想都没想,就用了邻接矩阵存储。因为平时的训练默认STL很笨重。真的很可惜。这题出了我们应该就有银了,不过事已至此,见好就收吧。
封榜的时候,我们队排名即将掉出100名,比赛是114名之前有奖。最后几分钟的时候由于一直在怼G题,而且没过就很绝望。比赛最终还是结束了,滚榜是真的刺激。从最后一名往上滚,最开始放出来的是封榜之前的排名,以及封榜后的提交记录,但是看不见结果,然后主持人一名一名查看结果,出了题队伍名次就跑到上面去。当看到滚到130名的时候,心想这个奖就稳了。最终我们是铜奖,马马虎虎吧。颁奖结束后,我们就去中街那边吃大餐了。
至此,我的ACM生涯结束了。