巅峰赛 #37 题解 | 非官方
本次题目猜测的总体难度如下,仅供参考:
题目编号 题目标题 难度 T1 午枫的幸运名单 普及−\color{orange}{普及-}普及− T2 宝藏密码 普及/提高−\color{yellow}{普及/提高-}普及/提高− T3 午枫的宝藏 普及/提高−\color{yellow}{普及/提高-}普及/提高− T4 午枫的罗盘 普及/提高−\color{yellow}{普及/提高-}普及/提高− T5 午枫的航海日志 普及/提高−\color{yellow}{普及/提高-}普及/提高− T6 午枫的密码本 普及+/提高\color{green}{普及+/提高}普及+/提高
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
T1. 午枫的幸运名单
题目大意
给一个正整数 nnn 和 nnn 个 字符串 SiS_iSi ,并且给出一个 PPP,判断 PPP 是否在字符串中出现过,并且输出出现的位置的 iii,如果没有出现则输出 -1。
解题思路
对于每一个输入的时候,直接判断输入的字符串是否等于 PPP 即可,但是如果用 solve\mathrm{solve}solve 的话,需要把答案记录下来,不能直接输出。
参考代码
单组测试样例时间复杂度:O(n)O(n)O(n)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
T2. 宝藏密码
题目大意
给你 nnn 条公式,每一条公式有一个共同解 xxx,而方程为 aix+bi=cia_ix + b_i = c_iai x+bi =ci ,其中 ai,bi,cia_i, b_i, c_iai ,bi ,ci 的位置可以调换。
解题思路
得出 xxx 所表示:
aix+bi=cia_ix + b_i = c_i ai x+bi =ci
aix=ci−bia_ix = c_i-b_i ai x=ci −bi
x=ci−biaix = \dfrac{c_i-b_i}{a_i} x=ai ci −bi
可以把所有 ui,vi,wiu_i, v_i, w_iui ,vi ,wi 可能的 ai,bi,cia_i, b_i, c_iai ,bi ,ci 枚举出来。如果 ci−bimod ai=0c_i-b_i\mod a_i=0ci −bi modai =0,则可以将这个答案压入一个 vector\mathrm{vector}vector,然后去重。由于答案为一,所以判断是否满足 aix+bi=cia_ix+b_i=c_iai x+bi =ci 即可。
参考代码
单组测试样例时间复杂度:O(n)O(n)O(n)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
T3. 午枫的宝藏
题目大意
有 nnn 个人。船长可以提出一个分配方案,如果投票超过半数则成功,否则船长被杀死。所有水手聪明、贪婪、互不信任,每个人在保证自己不被杀的前提下争取最大利益。求每个人能获取的金(不包括船长),且能保证自己活下来。压缩答案为:
R=(∑i=1ni×ri)mod (109+7)R = (\sum_{i=1}^n i \times r_i) \mod (10^9+7) R=(i=1∑n i×ri )mod(109+7)
解题思路
假设现在有 111 个人(不包括船长),那么他肯定投自己一票,票数过半,所以可以给自己利益最大化。
假设现在有 222 个人(不包括船长),那船长只需要令其中一个人同意,所以会给 222 号水手 111 个金,可以令 222 号水手举手。由于如果 222 号水手不同意,111 号水手就会决定分配,而 222 号水手则一点金都拿不到,所以 222 号水手一定会同意。得出 rrr 数组:
0,1,0,1,0,1,⋯0, 1, 0, 1, 0, 1, \cdots 0,1,0,1,0,1,⋯
接下来压缩答案,只有双数位的 rir_iri 才会对答案有贡献,所以如果 nnn 为偶数,则答案为 2+4+⋯+n2+4+\cdots+n2+4+⋯+n;否则答案为 2+4+⋯+(n−1)2+4+\cdots+(n-1)2+4+⋯+(n−1),而公式则为 n×(n+2)4\dfrac{n\times (n + 2)}{4}4n×(n+2) 。
参考代码
单组测试样例时间复杂度:O(1)O(1)O(1)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
T4. 午枫的罗盘
题目大意
有 nnn 条线,相邻两条线之间的夹角为 180∘k\dfrac{180^\circ}{k}k180∘ ,求有多少对垂直的线。
解题思路
首先观察题目,如果 kkk 是奇数是不可能有任何垂直的线。且如果 n<k2n < \dfrac{k}{2}n<2k ,则不可能有垂直的线。
和 000 垂直的第一条线为 k2\dfrac{k}{2}2k 。设 aaa 为 000 垂直的最后一条线,bbb 为与 000 垂直的线的组数。则对与所有都有 (a−k2+1)×b(a - \dfrac{k}{2}+1)\times b(a−2k +1)×b。而还有多余的线(n−an-an−a), (a+1,a+1+k)(a + 1, a + 1 + k)(a+1,a+1+k) 的区间有 (b−1)(b-1)(b−1) 条线;(a+1+k,a+1+2k)(a + 1+k,a+1+2k)(a+1+k,a+1+2k) 的区间有 (b−2)(b-2)(b−2) 条线。则是每一组就有
(b−1)×k,(b−2)×k(b-1)\times k, (b-2)\times k(b−1)×k,(b−2)×k,提取 kkk 出来则是 k×(b−1)+(b−2)+(b−3)+(b−4)+⋯+1k\times(b-1)+(b-2)+(b-3)+(b-4)+\cdots+1k×(b−1)+(b−2)+(b−3)+(b−4)+⋯+1,项数为 n−(a+1)k\dfrac{n-(a+1)}{k}kn−(a+1) 。最后运用(首项+末项)×项数2\dfrac{(首项 + 末项)\times 项数}{2}2(首项+末项)×项数 ,求出答案即可。
参考代码
单组测试样例时间复杂度:O(1)O(1)O(1)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
T5. 午枫的航海日志
题目大意
有 nnn 个数,有多少组数对 (p,q)(p,q)(p,q),使得序列存在 p,0,p,qp,0,p,qp,0,p,q。
解题思路
考虑这个问题可以先问一些问题:
* 对于每一个 ppp,应该选哪一个 000?当然是离 ppp 最近的那个 000,可以最大化后面 qqq 的个数。
* 对于每一个 000,应该选哪一个 ppp?当然是离 000 最近的那个 ppp,可以最大化后面 qqq 的个数。
我们可以用一个 suff\mathrm{suff}suff 数组,表示从当前位置到序列末尾有多少个不同数字个数,而且要记录下来每一个数字出现的位置。我们可以用 lower_bound 来查找后面的下标,再处理一下特殊情况就可以了。
参考代码
单组测试样例时间复杂度:O(N×nlogn)O(N \times n \log n)O(N×nlogn)。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
T6. 午枫的密码本
题目大意
给定一个字符串 SSS,将其拼接 kkk 次得出 S′S'S′,求 S′S'S′ 的 ASCII\mathrm{ASCII}ASCII 值的最长上升子序列的长度。
解题思路
首先看到 kkk 的最大值为 1010010^{100}10100,所以显然不能直接暴力拼接,考虑优化。假设字符串 SSS 为 zyxwvutsrqponmlkjihgfedcba,kkk 为 1010010^{100}10100,结果的值为 262626。由此得知,答案最大为 262626,因为是严格上升子序列,而英文字母只有 262626 个。所以 SSS 拼接 262626 次就可以了。
怎么判断 kkk 是否大于 262626 呢?kkk 是字符串,无法直接判断。我们可以先看 kkk 的长度。如果大于 222 则一定是拼接 262626 次。如果小于,直接换成 int 判断就行了。
最后,使用 dp\mathrm{dp}dp 求最长上升子序列即可。
参考代码
时间复杂度:O(m2)O(m^2)O(m2),其中 mmm 为拼接后字符串的长度。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------