“达梦杯”武汉理工大学新生程序设计大赛 题解

A.awa开小车

我们可以将“小车发射器”看作小车在某个位置、起始运动方向为某个方向的描述,那么考虑按照小车运行方向和位置进行模拟即可,在遇到没有触发过的导向板时执行相应的转向,计数,并将其标记为已经过,离开边界的时候结束模拟。

时间复杂度为O(n^3)

B.JokerXuan的明星梦

定义两个变量t0 与 t1 ,将他们的二进制的形式初始化为000000……与111111……,每次进行幸运数字的更新,同时以相同的方式更新这两个变量。当遇到“null”时,在当前幸运数字的二进制形式中找到0的位置,如果t0中的相应位置变成了1,那么就需要将这个0所在的位置改成1,其余同理。

C.What is ACM

签到题,循环判断每个位置上的字符S_i是不是关键信息,以及前一个位置S_{i-1}是不是关键信息,如果连续则说明属于同一个字符串,最后将所有字符串用空格隔开输出。

D.呼风唤雨

前缀和,枚举所有情况求ans,时间复杂度O(n)。

E.急急国王修公路

F. 绒绒的括号序列

考虑将T字符串左右拓展出一个合法的括号序列,通过拓展的方案数来确定S的数量。 为了避免重复计数,固定T串为扩展后S串上第一次出现T串的位置。

我们称一个括号序列的“匹配值”为其未匹配的左括号的数量,若匹配值为负数则其绝对值为未匹配的右括号数量。

我们知道,一个括号序列是合法的,当且仅当其每一个前缀的匹配值都是非负数,且整个序列的匹配值为0。

f[i][j]为在T串左边拓展i长度、j匹配值,其任何一个前缀的匹配值都是非负数,且保证i+1是第一次出现T串的位置的方案数。 设g[i][j]为在T串右边拓展i长度、匹配值-j,且其每一个后缀的匹配值都是非正数的方案数。可以发现g[i][j]其实和拓展i长度、匹配值j,且每一个前缀的匹配值都是非负数的方案数相等。

首先考虑g[i][j]比较简单,其转移方程可以直接列出


g[i][j]=g[i-1][j-1]+g[i-1][j+1]

然后对于f[i][j],我们考虑从g[i][j]中去掉一些部分来得到。 那么就需要考察一下f[i][j]g[i][j]有什么区别,fg多的唯一一个限制是要求i+1T串第一次出现的位置,那么我们就需要去掉会使得T串在i+1之前出现的位置。

如果T串在i+1之前出现,由于m-n\le n,这个T串一定是由左边i长度的拓展出的部分的一个后缀与T串本身的一个前缀(可以为空)构成的。

此处有T的一个前缀等于T_1的一个后缀,而T=T_1,所以其实T的这个前缀是T的一个Border,也可以称为公共前后缀。这样一来,前面长度为i的部分的后缀就是T去掉一个为Border的后缀之后的前缀部分,设Border长度为s_1,则i这部分的后缀实际上是T[1, n-s]。 那么是不是只要得到T的所有Border,然后直接去掉前面相应的部分就行了呢?当然是不行的,如果两个需要删除的部分满足其中一个是另一个的后缀,那么在去掉短的那种情况的时候就已经把长的去掉了。

此处在去掉T_1的情况时,T_2已经被去掉了。 那么这种情况怎么避免呢,继续考虑较短的那部分实际上是T的一个前缀,在T_2中同样包括这个前缀,换句话说,较短的这部分就是T_2在前i内这部分的一个Border。

我们考虑将T串的Border树建出来,每个点x表示T串长度为x的前缀,x的父节点是x的最大Border,那么只要在树上沿着树边向父节点走,就可以找到x串的所有Border,也就是说x子树内的串都含有长度为x的Border,所以我们只需要将所有需要删的长度对应位置打上标记,然后在Border树上dfs,遇到标记就直接删去贡献并停止向下dfs,避免重复删。

时间复杂度O(n^3)

G.神奇的礼物

假设三种礼物的数量分别为a, b,c 不妨设经过一次改变后变为 a-1, b-1, c+2, 考虑任意两者之间差的绝对值

发现与变换前任意两数之差的绝对值模3是相同的

不妨假设最后需要的结果为0,0,a+b+c, 那一定有(0-0)\%3=0, 即需要有(a-b)\%3=0, 对每种情况分别判断即可。

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字典树

对于a_i\ \ xor\ \ b_j > a_j\ \ xor \ \ b_i这个式子是不好计数的

但是求a_i xor b_i > a_j\ \ xor \ \ b_j或者a_i\ \ xor \ \ b_i < a_j\ \ xor \ \ b_j都很好计算

可以考虑如何利用这两个式子

对于a_i\ \ xor \ \ b_i > a_j\ \ xor \ \ b_j

x = a_i\ \ xor \ \ b_i,y = a_j\ \ xor \ \ b_j

肯定是如下形式: x = (....1....)_2y = (....0....)_2 即二进制下x、y的高前m位相同,高第m + 1位不同,且x的为1,y的为0 令z = b_i \ \ xor \ \ b_j 如果z的高第m + 1位为0,那么x \ \ xor \ \ z > y \ \ xor \ \ z 也就有a_i\ \ xor \ \ b_i \ \ xor \ \ b_i \ \ xor \ \ b_j> a_j\ \ xor \ \ b_j \ \ xor \ \ b_i \ \ xor b_j 整理得a_i\ \ xor \ \ b_j > a_j\ \ xor \ \ b_i,即所求式子

如果z的高第m + 1为1,则可以整理得a_i\ \ xor \ \ b_j < a_j\ \ xor \ \ b_i,对于答案就没有贡献

对于x < y也可以类比分析出来,只有z的高第m + 1为1才有贡献

使用01字典树以a_i\ \ xor \ \ b_i建树,同时在树上维护b_i的数量和即可

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-05 13:40
深圳拓智者科技有限公司 工程师 6500Kx12(过年那一个月4000) 大专
点赞 评论 收藏
分享
点赞 3 评论
分享
牛客网
牛客企业服务