第一题
标签:dfs、双指针
题意:给一棵树节点个数为n,现为每个节点赋权,要求每个节点权值不同、权值范围为1~n、奇数层节点权值和与偶数层节点权值和差值的绝对值不超过1。
思路:首先把奇数节点和偶数节点存储起来,得到奇数和偶数节点的个数分别为n1,n2(n1+n2=n)。设权值和为A=∑i=1ni,不难发现奇数节点的权值和为2A或者A−2A,且当奇数节点存在一个方案则偶数一定存在一个对应方案,因此只需要考虑奇数节点即可。
此时问题转换为,1~n中选取n1个数x1,...,xn1,使得∑i=1n1xi=2A或=A−2A。下面只以2A为例解释,n1个数和应满足条件∑i=1n1i≤2A≤∑i=n−n1+1ni,即n1个数和范围的最小、最大。当在这个范围内则一定有解(我猜的,不会证明)。
当满足条件进行赋权过程,构造一个bool数组st[n]标记赋给奇数的值,初始n1个节点权值赋为1,...,n1即最小的情况,并维护两个指针l,r初始l指向n1,r指向n,每次用r指向的值预替换l指向的值,若替换后超过目标值(即2A)则l左移,若替换后不超过目标值则直接替换,并将l,r左移并设st[l]=true,st[r]=flase,直到等于目标值。此时标记结束,为true的赋值给奇数节点、为false的赋值给偶数节点即可。
第二题
标签:二分答案
题意:只有小写字符的字符串,设字符串的长度为n、字符串字符种类数为m,如(aabc,n=4 m=3)则字符串的价值为n*m。现给一个字符串s,需要将字符串分为连续的k份,得到k个子串s1,...,sk(s=s1+,...+sk)。现请最小化 k个子串价值的最大值。
思路:k个子串实际就是每次划分后的前缀。设子串价值最大值为Max_Val,初始化l=0,r=26∗500000,现二分Max_Val,取m=2l+r每次check取最长前缀si使得si的价值小于等于m,若划分的子串个数小于等于k则更新r=m,否则更新l=m+1。最终输出l即可。
第三题
标签:水题
给一个字符串s,求si=si−1的对数,for循环一遍判断计数就行。