Codeforces Round #455 (Div. 2)
A. Generate Login
题目描述:给出两个字符串,分别取字符串的某个前缀,使得两个前缀连起来的字符串的字典序在所有方案中最小,输出该字符串。
solution
为保证字典序最小,第二个字符串只会选第一个字符,然后先选上第一个字符串的第一个字符(因为不能为空),接着从第二个字符开始,如果该字符小于第二个字符串的第一个字符,那么选上,否则停止,输出答案。
时间复杂度:(O(n))
B. Segments
题目描述:给定一个数(N),考虑数轴上的所有端点均为整数且在([0, N])的线段,显然有(frac{n(n+1)}{2}),现将这些线段置于不同层,使得同一层的线段不重叠(端点不算),问最少要多少层?(下图为(N=4)时)
solution
考虑长度为一的线段,所有与该线段重叠的线段均在不同层,所以答案至少为((frac{n}{2}+1)frac{n+1}{2}),事实上,这个就是答案,题解中也没讲得很清楚,只是说可以构造出来
时间复杂度:(O(n))
C. Python Indentation
题目描述:给出一段简略版无缩进的Python
代码(只有for
和简单语句),问有多少中缩进满足Python
语法。
solution
设(f[i][j])表示到第(i)条语句缩进了(j)次,当第(i-1)条语句为for
时,第(i)条语句必须缩进,所以(f[i][j]=f[i-1][j-1]),若不是for
则假设第(i)条语句缩进(j)次,那么这个状态可以从(f[i-1][k], (k>=j))转移过来,也就是后缀和。
时间复杂度:(O(n^2))
D. Colorful Points
题目描述:给定一个只有小写字母的字符串,每次操作选出字符串中与相邻位字母不一样(任意一个即可)的位置,然后删除,剩下的拼接在一起,问能执行多少次这样的操作
solution
因为如果与相邻位字母都相同的话,该字母不会被删除,所以可以把相邻的相同字母看成一组,假设有(D)组,每组有(G(D))个字母,因此每一次操作只会把每一组的最左边和最右边删掉。每次求出最少操作数使得某个(G(D)=0),更新答案,并更新每组剩下的字母个数,并且进行必要的合并,这里的时间复杂度为(D),但每次更新后字母数至少减少(D)个,因此总的时间复杂度为(O(n))
时间复杂度:(O(n))
Coprocessor
题目描述:给定一个拓扑图表示依赖关系,并给定每个点(任务)必须在主进程执行还是副进程执行。开始时在主进程,每个任务执行前,它所依赖的任务必须已经执行,在主进程中可以调用副进程,每次调用时都可以执行若干个任务,但每个任务的依赖任务必须在该次调用中或已经执行了,副进程结束后会返回主进程。问至少需要调用多少次副进程才能完成所有任务。
solution
从叶子节点往上dp,假设当前节点为(i),(f[i])表示完成该子树的所有任务至少需要调用多少次副进程。如果节点(i)必须在主进程执行,那么((j)为(i)的儿子)
如果(i)必须在副进程执行,则(f[i]=max){(f[j])}
为了方便,可以添加一个主进程任务(0),它的依赖为所有进程,最终答案就是(f[0])
时间复杂度:(O(n))
F. AND-permutations
题目描述:给定一个整数(N),寻找两个(N)排列:
- (p_i eq i)且(p_i & i=0)
- (p_i
eq i)且(p_i & i
eq 0)
若不存在,则输出NO
solution
考虑第一个排列。
当(N)为奇数时,不存在第一个排列,因为当(i)为奇数时,(p_i)为偶数(否则二进制最低位为(1)),但奇数个数与偶数个数不相等,所以无解。
当(N)为偶数时,注意到((2^k+i) & (2^k-i-1))等于0((i geq 0)),所以可以找出最大的(k)使(2^k leq N),然后构造解,更新(N=2^{(k+1)}-N-2),直至(N=0)
考虑第二个排列。
手工构造可知,当(N<6)时无解,当(N=6)时,解为(3,6,2,5,1,4),当(N=7)时,解为(7,3,6,5,1,2,4)。
当(N>7)时,因(8)~(15), (16)~(31), (32)~(63), ... , 每组的最高位一致,所以这些数各组循环移动一位即可。
时间复杂度:(O(n))