T1-午枫的字符串加密
首先能想到,移动 262626 次等于没动。所以 mmm 可以先对 262626 取模。
然后我们直接用减法计算原字符串,如果某一个字符 ccc 出现了 c<'a' 的情况,说明在加密过程中由 z 变 a 了,此时直接加上 262626 即可。
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n)O(n)O(n)
Code:
T2-小午的质因子统计
O(n)O(\sqrt{n})O(n ) 的质因数分解相信大家人人都会,就不赘述了。
但是 O(nn)O(n\sqrt{n})O(nn ) 在这题会超时,所以我们需要 O(nlogn)O(n \log n)O(nlogn) 计算。
考虑到根号算法耗时在寻找质因子的时候,所以筛法记录每个数的最小质因子。采用埃氏筛。
时间复杂度:O(nlogn)O(n \log n)O(nlogn)
空间复杂度:O(n)O(n)O(n)
Code:
T3-午枫的字符串移动
这题有一个很引人注目的点:n≤104n \leq 10^4n≤104。这意味着允许 O(n2)O(n^2)O(n2) 算法!
首先考虑到移动 nnn 次等于不动,所以求得 0≤m<n0 \leq m<n0≤m<n。
直接枚举 mmm,然后模拟移动的过程,最后判断是否和 s′s's′ 恰好相差 kkk 字符。
判断可以使用双指针,如果 sl=sr′s_l=s'_rsl =sr′ ,则成功匹配;反之匹配失败,需要在 sr′s'_rsr′ 前添加一个字符。统计添加的字符数量是否恰好为 kkk 即可。
时间复杂度:O(n2)O(n^2)O(n2)
空间复杂度:O(n)O(n)O(n)
Code:
T4-午枫的01串翻转
如果字符串没有 0,那么显然答案为 000;
如果字符串只有 111 个 0,那么我们要争取做一次操作让 0 变多。考虑到 rrr 的位置一定会变成 0,所以如果 rrr 越靠后,距离越远。统计 0 后面的 1 的位置,如果少于 222 个则无可奈何,否则选择最后一个 1 与最前的一个 1 即可。
如果字符串有 222 个或者更多 0,那么显然,我们至少可以将其中之一作为 lll。第一个 0 显然是需要我们保留下来作为最远距离的,所以我们选择其他的任意一个 0 作为 lll。如果结尾是 0,那么无需操作也能得到最远距离;如果结尾是 1,那么令其为 rrr ,一次操作之后,结尾又会变成 0。综上所述,我们需要的 0 一定是第一个 0 和结尾。
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n)O(n)O(n)
Code:
T5-午枫的双向奔赴
约定:从 uuu 走到 vvv 的最短路长度 LLL 记作 L=u→vL=u \rightarrow vL=u→v。
如果我们知道 L1=1→kL_1=1 \rightarrow kL1 =1→k 和 L2=n→kL_2=n \rightarrow kL2 =n→k,那么他们需要多长时间才能见面呢?显然,有一个人会先到,然后等待另一个人到。所以是 max(L1,l2)\max(L_1,l_2)max(L1 ,l2 )。
如果我们对于所有的 kkk 都能知道 L1,L2L_1,L_2L1 ,L2 的话,就可以 O(n)O(n)O(n) 打擂台求出最短时间了。当然求出编号也不是难事,以后不再赘述。
很显然,L1L_1L1 可以跑一遍单源最短路,L2L_2L2 同样可以。
所以我们跑两遍单源最短路就行了!
时间复杂度:O((n+m)logm)O((n+m) \log m)O((n+m)logm)
空间复杂度:O(n+m)O(n+m)O(n+m)
Code:
T6-午枫的字符串制造
显而易见的,回文串最多只有一个字符出现次数是奇数。
奇偶性我们可以简单地用 0/10/10/1 代替。所以,我们有 262626 个字母,每个字母有 0/10/10/1 两种状态。所以我们可以使用状态压缩!(题目1024MB也是一种提醒)
所以,dpmaskdp_{mask}dpmask 表示当目前前缀状态为 maskmaskmask 的时候的合法子串数量(目前,是指目前处理到了哪一位)。
首先记录一下目前的前缀 ppp,然后将答案加上 dppdp_pdpp 。
同时,我们知道,有可能会有一个字母出现奇数次。枚举这个字母,并记录答案。
最后,记得用 ppp 更新 dppdp_pdpp 的值。
注意下,一开始 dp0=1dp_0=1dp0 =1,因为任何字母都出现 000 次。
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n+226)O(n+2^{26})O(n+226)
Code: