竞赛讨论区 > 【题解】肇庆学院"菜鸟杯"程序设计竞赛2019(同步赛)
头像
_Jessie
编辑于 2019-12-29 20:50
+ 关注

【题解】肇庆学院"菜鸟杯"程序设计竞赛2019(同步赛)

update:
由于办赛经验不足以及我们在准备、审题、验题各个环节上的疏忽,
且赛时答疑者并非E题出题者没有意识到标程及数据的错误,
导致E题标程及数据有误,却没有及时发现并更正。
在此再次向参赛选手们表示我们最最最诚挚的歉意,希望各位大佬轻喷。

特别感谢评论区几位大佬的提醒,经过我们的讨论,已经修改了标程及数据,同时还有不合理的【石头可能重叠】的情况,现已rejudge了赛时代码。
emmm_ydfq

另外更改了E题的题解
E 一步两步是魔鬼的步伐
这是一道经典的二分题,最大化最小值。首先题目要求的是石头之间距离以及石头和对岸距离的中的最小值,由于可以去掉M个石头,且位置未知,所以有许多种方案,每种方案都会产生一个最小值,要求在这些可能的最小值中找到最大的一个。
所以这道题去二分一个最小值,并检验在当前二分出的最小值的情况下,假面超人能否在跳到对岸的过程中保持
1、跳跃距离不小于当前最小值(石头间距小于当前最小值时必须去掉石头)
2、最终去掉的石头数x不超过m(超过m说明当前最小值过大,导致需要去掉的石头过多)
需要特别注意的是:
假面超人的最后一跳是跳上河岸的,而河岸不能作为石头去掉,所以检验时应该特判最后一跳,
若最后一跳的距离小于二分的最小值,可直接将最后一颗石头消去。

----------以下为原题解

首先,关于本场比赛,由于我们的经验不足,对大家造成的影响,说声抱歉。

本次比赛题目难度预估是 F J K L < D G H I < A B C E
但似乎现实很残忍。。。

A 解锁专家
做这种题呢,当你没什么思路的时候,就应该多看看诗,你会发现每一句的头一个字,它们没什么特别的,但是它们凑在一起就有点故事了。
其实这题是个斐波那契问题,如果没有限制条件1的话,就是裸的斐波那契。

现在,假设没有限制条件1。设ans[i]表示n = i时的答案。
那ans[1] = 2 (1, 0), ans[2] = 3(01, 00, 10), ans[3] = 5(000, 001, 010, 100, 101)
那么就满足斐波那契的递推式了即:ans[i] = ans[i - 1] + ans[i - 2] (i >= 3)
具体可以这么理解:
对于ans[ i ] 可以理解为现在有 i 位二进制位还没确定的方案数
当i = 3时,对二进制最高位编号为3,其他位编号依次减1,最低位编号为1
我们讨论第3位的取值情况
①、第3位取0,那就只是确定了第3位,还有两位没确定,那就变成了n = 2的情况,那这种情况的方案数就是ans[ 2 ];
②、第3位取1,那第二位只能是0,所以确定了两位,还有一位没确定,那就变成了n = 1的情况,那这种情况的方案数就是ans[ 1 ];
故总的方案数就是ans[ 3 ] = ans[ 2 ] + ans[ 1 ]
按这个思路,就能得到: ans[ i ] = ans[ i - 1 ] + ans[ i - 2 ] (i >= 3)

但现在有限制条件1,即x>0,上面的答案都包含了0这种情况,那只要减去这种情况就是最终答案了,所以最终答案就是: ans[n] - 1

B 麻烦的杰西
很容易想到对于每一个位置i,只要
从左边取到l ( l <= j < i , hj >= hi ) , 从右边取到r ( i+1 <= j <= r, hj>=hi )
然后答案ans = max( ans , sum( l , r ) ) 即可
不过由于n的范围为1e5,这样的做法O(n^2)肯定会超时。所以对于每个位置做一个记录。
l[i]表示位置i往左能找到的 不小于当前位置高度的 最长连续的 最左端的位置。如何更新l[i],对于每个位置i,假设h[i]<=h[l[i]-1],说明最左端的左边位置高度不小于当前位置i的高度,所以l[i]就可以沿用l[i]-1的l[],即:l[i]=l[l[i]-1]。
对于r[i] 同理,这样就避免了O(n^2)的做法。

C 最大模数
通过二项式定理列出n取1~5的情况:
图片说明
% a²后有:
图片说明
显然,对n为偶数的情况,结果都是2。对n为奇数的情况,结果为2 * n * a。
此时问题转化为 求2 * n * a % ( a² ) 的最大值。
初步判断,知道2 * n * a = a² 时n的取值,把n-1代入上式,结果就是最大值。
进一步,通过化简2 * n * a = a² ,可以得到 n = a / 2。 故需要再考虑a的奇偶性:
①、当 a 为奇数的时候
由于 2 * n * a = 2 * (a / 2) * a < a² , 所以不需要取n-1,此时Ra就是最大模数了。
最大模数就是 2 * ( a - 1 ) / 2 * a = a² - a 。
②、当 a 为偶数的时候
由于 2 * n * a = 2 * (a / 2) * a = a² , 此时Ra = 0,所以取n-1,即n = a / 2 - 1。
最大模数就是 2 * a * ( a / 2 - 1 ) = a² - 2 * a 。

D 米多立亚
对于这种字符串交换找最小字典序的字符串题目类型,需要先观察对于'0' , ' 1' , '2' 这三种字符哪一种是特殊的,特殊体现在就是在三者之间,只有自己才有的特性,发现相邻的 '01','10','12','21' 可以任意交换成 '10','01','21','12'。
也就是'1'字符可以和'0','2'任意交换,同时只有'0','2'两者之间是不可交换的。举个例子,'102' 可以交换成'012','021'。无论怎么交换'0'和'2'的相对位置都是不能改变的。所以答案就是,在所有'0','2'相对位置不变的情况下,把字符串中所有的'1’都放在第一个'2'前面。

E 一步两步是魔鬼的步伐

F 参赛
首先,由于 天梯赛队伍 一定可以分拆成 icpc队伍,故不存在 能组成天梯赛队伍但不能组成icpc队伍 的Second情况。(10+1 -> 3*3+2)
由于学生和教练的人数不确定,又由于一个教练可以兼任多个队伍的教练。所以可以先组出三人队伍n/3支,剩下n%3人作为教练,那么只要判断教练人数是否不小于三人队伍支数即可。但会出现n%3=0的情况(没有教练),这种情况需要从n/3的三人队伍中,取出三人作为教练,故此时队伍变为n/3-1支,教练3人,再进行判断即可。天体赛队伍同理。

G 数数有多少个水坑
本题题意:将j e s i上下左右直接相连的作为一个水坑,问有多少个这样的水坑。
思路:广搜或者深搜都可以。
枚举矩阵中的每一个点,
假如不是j e s i中的其中一个,就跳过。
假如是,就在这个点展开广搜或者深搜。
将这个点上下左右的点都搜一遍,
假如不是j e s i中的其中一个,就跳过。
假如是,就在这个点继续搜。
直到范围内搜不到有关j e s i 的点,就退出。
搜索过程中有关jessie的点,要置换为其他特殊字符可减少重复搜索。
然后,就将得到的水坑数量+1。
然后继续枚举完整个图,就能得到水坑数量。

H 你相信爱情吗?
织女固定在星球的n位置,牛郎从n位置开始,每次跳m个单位。可知牛郎一定会在n/gcd(n,m)次跳跃后回到n位置。而回到n位置之后再次出发的跳跃步骤和第一次从n位置出发的跳跃步骤一致,所以牛郎若第一次回到n位置时若无法获得所有的钻石,那么在之后的跳跃中也无法获得所有的钻石。
牛郎会进行n/gcd(n,m)次跳跃,要获得n个钻石,则n/gcd(n,m)=n,即gcd(n,m)=1。故gcd(n,m)=1时答案为n,否则无法完成答案为-1。

I 师姐我想要红包
首先尽量不要用pow函数,计算时精度误差较大。
数据范围不大,本题的解法就是深搜+简单剪枝,不剪枝直接深搜会超时。
每次搜索当前点去往哪个位置即可。在搜索下一个点前,标记当前走过的点,在深搜结束回溯后再取消标记,这是深搜基本的操作。每次深搜到走完n个点后,更新最短距离。
剪枝是搜索过程中,发现当前解的距离已经比已知的最短距离长了,就直接return;结束不再继续搜索。

J 试试划水
题意很简单,就是计算字符串s中存在的ZQU的个数。(Z、Q、U有先后顺序,但不需连续)。
给出的程序时间复杂度达到O(n^3),但数据范围达到1e5,必然会超时。下面给出本题 O(n) 的解法。思路是这样的:遍历字符串中的’Q’,每次累计这个’Q’之前的所有’Z’与这个’Q’之后的所有‘U‘的组合方案,即个数相乘。
先记录遍历整个字符串,得到‘U’的总数cntU。初始‘Z’的个数cntZ=0,在遍历字符串时,不断记录在当前’Q’之前的‘Z’的个数cntZ(遇到’Z’则cntZ++);不断更新在当前’Q’之后的’U’的个数cntU(遇到’U’则cntU--);只要一遇到’Q’,此时在这个’Q’之前有cntZ个‘Z’之后有cntU个’U’,则累计与这个’Q’组成的’ZQU’的方案数ans+=cntZ*cntU。

K 钟Sir的任务
因为在相同长度的情况下,前置位的字符越小,字典序必然越小。又由于可以进行n次操作(不会出现最小字符无法换到最左端的情况),所以贪心地从右往左将较小的字符往左移即可。限制一种操作只能使用一次,最直接的方式就是利用一个标记数组来记录哪些位置的操作被使用过。
在所有当前可操作的位置里,从右往左将字典序更小的字符往前置位交换。这样操作完一轮后,整个字符串若发生变化,则可能产生新的还没有操作过但符合上述交换条件的位置(如 5 4 1 3 2 操作一轮后得到 1 5 4 2 3 ,此时产生新的 4 2 是还没有操作过,且2字典序更小可往前置位交换);否则若字符串没有发生变化,说明已经没有可执行的交换,那么就已经得到答案了。
故需要进行多轮交换,由于数据范围比较小,暴力地尝试n轮交换,时间复杂度O(n^2)也能时限内跑完。当然其实不可能达到O(n^2)复杂度。

L JAJA_Xin的小心思
贪心。先判断所有袋子压缩后的大小是否小于m,说明可以放入行李箱,否则一定放不进去,输出-1。再将所有行李的被压缩空间,从大到小排序,直接贪心地选择能被压缩更多的行李,当发现已经可放入行李箱时,就不用再压缩之后的行李了,不断计算压缩值统计压缩数量即可。

全部评论

(4) 回帖
加载中...
话题 回帖

等你来战

查看全部

热门推荐