A
开个桶记一下。
时间复杂度 (Oleft(n+a ight))。
B
按长度从小到大排序,显然如果存在合法的排列那这样子一定是其中一种(长度相同的字符串一定要相同,可以随便换)。
暴力找是 (Oleft(left|S ight|^2 ight)) 的(相邻两个最多配长度差次),KMP 可以做到 (Oleft(nleft|S ight| ight)),还要加上排序的 (Oleft(nlog nleft|S ight| ight))。
C
因为要两个不同的序列,所以枚举当前序列删哪个数,看一下之前有没有这个和,做完后再枚举一遍丢进 map
。
时间复杂度 (Oleft(sum nlogsum n ight))。
D
三个数字在两个数字的基础上添加一个数字,相邻的两个差值要相等。
四个数字在三个数字的基础上添加一个数字,不存在合法的方案。
更多的数字都建立在四个数字的基础上,不存在合法的方案。
然后随便枚举一下就是了。
时间复杂度 (Oleft(nlog nlog x ight))。
E
能被 (25) 整除无非最后两位是 ( exttt{00 25 50 75}),尝试把它们移到最后即可。
找到离结尾最近的最后两位数字(优先找最后一位数字),它们分别位于 (x) 和 (y) 位置。需要注意移动时候出现前导 (0) 的情况:
- (x) 位于开头且开头第二个数字是 (0) 且 (y) 不是开头第二个(如果是就说明之前没有 (0),先移 (y) 肯定不会出问题)。
- (y) 位于开头且开头第二个数字是 (0)。
这两种情况需要向前找到第一个不为 (0) 的数,设其位于 (z) 位置,并把它换到开头。
至于 (z) 是不是在我们选取的位置不重要,因为如果是的话可以先往后换。
比如说 (20053),先变成 (20035),再变成 (32005),最后变成 (30025)。
但细心的同学可能又会发现,如果这个数在选取的位置并且之前没有非 (0) 数了呢?
比如说 (20050),应该不存在以 ( exttt{25}) 结尾的方案。
这是会出错的。但是这种情况就算这么算了,也不会影响答案,另一种情况中的移动次数一定会更小。比如说上例以 (50) 结尾就好了。
尝试分类讨论,首先 (x) 和 (y) 不可能均是 (0)。
- 找不到 (oldsymbol z)。
- 以 (x) 开头,此时 (x) 必定为 (5)。此时不管后面有几个 (0) 都没事,肯定直接合法了,不用管。
- 以 (y) 开头,此时 (x) 必定不为 (0),与找不到 (z) 矛盾,不存在这种情况。
- 选取的位置后面有 (0)。
- 选取的位置上的数是 (5),在 ( exttt{50}) 的时候会直接将选取的位置向后换。
- 选取的位置后面没有 (0),在 ( exttt{00}) 的时候会直接将选取的位置向前换。
然后就做完啦!时间复杂度 (Oleft(log n ight))。
F
令 (f_{i,j}) 表示走到 (i) 位置拿着第 (j) 把伞的最小疲劳值。若 (j) 是 (0) 则代表没有拿伞。
走回头路显然不优,所以没有后效性。
时间复杂度 (Oleft(am ight))。
为什么不能贪心呢?不同伞需要走的路程是不同的。但类似单调队列,靠前还重的肯定没有用了。