“达梦杯”武汉理工大学新生程序设计大赛 题解
A.awa开小车
我们可以将“小车发射器”看作小车在某个位置、起始运动方向为某个方向的描述,那么考虑按照小车运行方向和位置进行模拟即可,在遇到没有触发过的导向板时执行相应的转向,计数,并将其标记为已经过,离开边界的时候结束模拟。
时间复杂度为。
B.JokerXuan的明星梦
定义两个变量t0 与 t1 ,将他们的二进制的形式初始化为000000……与111111……,每次进行幸运数字的更新,同时以相同的方式更新这两个变量。当遇到“null”时,在当前幸运数字的二进制形式中找到0的位置,如果t0中的相应位置变成了1,那么就需要将这个0所在的位置改成1,其余同理。
C.What is ACM
签到题,循环判断每个位置上的字符是不是关键信息,以及前一个位置
是不是关键信息,如果连续则说明属于同一个字符串,最后将所有字符串用空格隔开输出。
D.呼风唤雨
前缀和,枚举所有情况求ans,时间复杂度O(n)。
E.急急国王修公路
F. 绒绒的括号序列
考虑将字符串左右拓展出一个合法的括号序列,通过拓展的方案数来确定
的数量。
为了避免重复计数,固定
串为扩展后
串上第一次出现
串的位置。
我们称一个括号序列的“匹配值”为其未匹配的左括号的数量,若匹配值为负数则其绝对值为未匹配的右括号数量。
我们知道,一个括号序列是合法的,当且仅当其每一个前缀的匹配值都是非负数,且整个序列的匹配值为0。
设为在
串左边拓展
长度、
匹配值,其任何一个前缀的匹配值都是非负数,且保证
是第一次出现
串的位置的方案数。
设
为在
串右边拓展
长度、匹配值
,且其每一个后缀的匹配值都是非正数的方案数。可以发现
其实和拓展
长度、匹配值
,且每一个前缀的匹配值都是非负数的方案数相等。
首先考虑比较简单,其转移方程可以直接列出
然后对于,我们考虑从
中去掉一些部分来得到。
那么就需要考察一下
和
有什么区别,
比
多的唯一一个限制是要求
是
串第一次出现的位置,那么我们就需要去掉会使得
串在
之前出现的位置。
如果串在
之前出现,由于
,这个
串一定是由左边
长度的拓展出的部分的一个后缀与
串本身的一个前缀(可以为空)构成的。
此处有的一个前缀等于
的一个后缀,而
,所以其实
的这个前缀是
的一个Border,也可以称为公共前后缀。这样一来,前面长度为
的部分的后缀就是
去掉一个为Border的后缀之后的前缀部分,设Border长度为
,则i这部分的后缀实际上是
。
那么是不是只要得到
的所有Border,然后直接去掉前面相应的部分就行了呢?当然是不行的,如果两个需要删除的部分满足其中一个是另一个的后缀,那么在去掉短的那种情况的时候就已经把长的去掉了。
此处在去掉的情况时,
已经被去掉了。
那么这种情况怎么避免呢,继续考虑较短的那部分实际上是
的一个前缀,在
中同样包括这个前缀,换句话说,较短的这部分就是
在前
内这部分的一个Border。
我们考虑将串的Border树建出来,每个点
表示
串长度为
的前缀,
的父节点是
的最大Border,那么只要在树上沿着树边向父节点走,就可以找到
串的所有Border,也就是说
子树内的串都含有长度为
的Border,所以我们只需要将所有需要删的长度对应位置打上标记,然后在Border树上dfs,遇到标记就直接删去贡献并停止向下dfs,避免重复删。
时间复杂度。
G.神奇的礼物
假设三种礼物的数量分别为,
,
不妨设经过一次改变后变为
, 考虑任意两者之间差的绝对值
发现与变换前任意两数之差的绝对值模3是相同的
不妨假设最后需要的结果为, 那一定有
, 即需要有
, 对每种情况分别判断即可。
H.小F的圣诞树
I.优雅 太优雅了
题目意思即 讨论不等式 min(A[l],A[l + 1],....A[r − 1],A[r]) >= gcd(A[l],A[l + 1],....A[r − 1],A[r + 1]) 成立的条件 我们可以转换一下 求不成立的条件 首先我们知道 对于区间[l, r] min{A[l,...., r]} >= gcd({A[l,...., r]}) 肯定是成立的 那么 考虑变化的点 明显题目里面的区间gcd A[r] 换成了 A[r + 1] 讨论: 1、A[r] > A[r + 1] : 1) A[r + 1] > min{A[l],....,A[r - 1]} 那么明显 区间[l, ... , r - 1, r + 1]的最小值在 [l, ... r - 1]取得 故 gcd({A[l, ..., r - 1, r + 1]}) < min{A[l, .... , r - 1]} == min{A[l, .... , r - 1, r]} (因为A[r] > A[r + 1] [l,... ,r]最小值 所以也不会在A[r]处取得) 2)A[r + 1] < min{A[l], .... , A[r - 1]} 也就是说区间[l, .... , r - 1, r + 1] 的最小值在A[r + 1] 取得 => gcd({A[l, ..., r - 1, r + 1]}) < A[r + 1] < min{A[l], .... , A[r - 1]} 同时 A[r + 1] < A[r] 所以 gcd({A[l, ..., r - 1, r + 1]}) < A[r + 1] < min{A[l], .... , A[r - 1], A[r + 1]} 得证 2、A[r] <= A[r + 1] 对于不等式 min{A[l,...., r]} >= gcd({A[l,....r - 1, r + 1]}) 显然若是 A[r] 不是区间[l, r] 的最小值 即 A[r] > min{A[l,...., r - 1]} 而 min{A[l,...., r]} = min{A[l,...., r - 1]} >= gcd({A[l,....r - 1]}) >= gcd({A[l,....r - 1]}, A[r + 1]) 那么只需考虑A[r] == min{A[l,...., r]}的情况 那么原不等式等价于 A[r] >= gcd(A[l],A[l + 1],....A[r − 1],A[r + 1]) 当不等式右边的最大值 gcd(A[r - 1], A[r + 1]) > A[r] 的时候那么就是不等式不恒成立的情况出现了 即(l = r - 1) 这时候数组是rude A[r] > A[r + 1] 时 A[r] > gcd(A[r - 1], A[r + 1]) 恒成立 所以我们只需对每个A[i] 看是否存在 A[i] < gcd(A[i - 1], A[i + 1]) 若存在则输出 rude 若不存在则输出 elegant
J.逆序对
知识点:01字典树
对于这个式子是不好计数的
但是求或者
都很好计算
可以考虑如何利用这两个式子
对于
令
肯定是如下形式:
即二进制下
的高前
位相同,高第
位不同,且
的为1,
的为0
令
如果
的高第
位为0,那么
也就有
整理得
,即所求式子
如果的高第
为1,则可以整理得
,对于答案就没有贡献
对于也可以类比分析出来,只有
的高第
为1才有贡献
使用01字典树以建树,同时在树上维护
的数量和即可