为了让大家看到我 T5 的唐诗做法特地写出了这篇全题解
T1
个人难度:红中
由于是 1,2,31,2,31,2,3,所以考虑循环解决,用 A1,A2,A3A_1,A_2,A_3A1 ,A2 ,A3 代替 a,b,ca,b,ca,b,c。
时间复杂度 O(1)O(1)O(1)。
T2
个人难度:红上
笑点解析:第一次交交成 Python 了。好在编译错误不算罚时。
显然,我们只需要把每个数变成当前最大值就行了。
时间复杂度 O(n)O(n)O(n)。
T3
个人难度:红下
跟我的 PY 说去吧。
* Python 的 str 变量有 lower 和 upper 函数,可以将字母自动转小/大写。
* Python 也有三目运算符,它的形式是这样的:a if b else c,其中 b 为条件,a 为 b 成立的结果,c 为 b 不成立的结果。
时间复杂度 O(∣s∣)O(|s|)O(∣s∣)。
T4
个人难度:红上
为了避免因为贪心变橙所以只有 444 个元素是吧,但是你 T2 都不装了这你还装啥。
依旧考虑循环解决。优先选卡牌的值最大的。
时间复杂度 O(1)O(1)O(1)。
T5
个人难度:黄中(假)
醋来咯。
冷知识,999 宫格不一定是 999 宫格。它的长度和宽度的范围是 [1,103][1,10^3][1,103] 中的任意一个,但是在这题中恰好都是 333 罢了。
所以我们考虑如何快速求出在 AAA 中是否有这个 999 宫格。
这个,那个,不是暴力就行了吗?
你的____何在
二维字符串哈希
首先回顾一下一维字符串哈希。
例如一个数列 A=[1,2,3,4,5]A=[1,2,3,4,5]A=[1,2,3,4,5],判断 B=[3,4]B=[3,4]B=[3,4] 是否为它的子段。
我们运用前缀和思想,令 A′=[1,12,123,1234,12345]A'=[1,12,123,1234,12345]A′=[1,12,123,1234,12345](Ai′=Ai−1′×10+AiA'_i=A'_{i-1}\times 10+A_iAi′ =Ai−1′ ×10+Ai ),B′=34B'=34B′=34。
然后呢,我们只需要判断是否存在一个正整数 iii 使得 Ai′−102×Ai−2′=B′A'_i-10^2\times A'_{i-2}=B'Ai′ −102×Ai−2′ =B′ 即可。显然当 i=4i=4i=4 时,符合条件。所以 BBB 为 AAA 的字段。
而二位字符串哈希就在一维的基础上加一维就行了。
这是矩阵 A=[123456789]A=\begin{bmatrix}1 & 2 & 3\\4 & 5 & 6\\7 & 8 & 9\end{bmatrix}A= 147 258 369 ,判断 B=[5689]B=\begin{bmatrix}5 & 6\\8 & 9\end{bmatrix}B=[58 69 ] 是不是它的子矩阵。
我们首先按照一维字符串哈希的方法,给每一行都哈希一次,A′=[112123445456778789]A'=\begin{bmatrix}1 & 12 & 123\\4 & 45 & 456\\7 & 78 & 789\end{bmatrix}A′= 147 124578 123456789 ,B′=[5689]B'=\begin{bmatrix}56\\89\end{bmatrix}B′=[5689 ]。
然后再按照上面的方法一行一行比对就行了。
但是如果 999 宫格变了个形状,从 3×33\times 33×3 变成了 1000×910001000\times \frac{9}{1000}1000×10009 呢?这样的话就会运行 103×103×103=10910^3\times 10^3\times 10^3=10^9103×103×103=109 次,不能通过。
我们可以换个不一样的乘数 (如 100010001000),然后再竖着做一遍哈希操作。
A′′=[112123100412045123456100400712045078123456789]A''=\begin{bmatrix}1 & 12 & 123\\1004 & 12045 & 123456\\1004007 & 12045078 & 123456789\end{bmatrix}A′′= 110041004007 121204512045078 123123456123456789 ,B′′=56089B''=56089B′′=56089。
然后呢?回忆一下二维前缀和是怎么查询的。
没错!我们只需要看看是否存在两个正整数 i,ji,ji,j,使 Ai,j′′−Ai−2,j′′×10002−Ai,j−2′′×102+Ai−2,j−2′′×10002×102=B′′=56089A''_{i,j}-A''_{i-2,j}\times 1000^2-A''_{i,j-2}\times 10^2+A''_{i-2,j-2}\times 1000^2\times 10^2=B''=56089Ai,j′′ −Ai−2,j′′ ×10002−Ai,j−2′′ ×102+Ai−2,j−2′′ ×10002×102=B′′=56089
就行了。很显然,有一个符合条件的答案:i=3,j=3i=3,j=3i=3,j=3。
这样子,我们就可以以 O(1)O(1)O(1) 的时间查询所有子矩阵的哈希值,总时间复杂度为 O(nm)O(nm)O(nm),与矩阵 BBB 的大小无关。
注意到当数据范围很大时这种办法会超过 int 等数据类型容纳的范围,所以我们实现的时候加个取模(自然溢出相当于对 2642^{64}264 取模)就能在 unsigned long long 范围内完成了。当然,乘数也不能用 10,100010,100010,1000 了,因为他们有很明显的乘方关系,随便一组数据都会 WA。
注意:这种取模操作不能保证对于所有的数据都能 AC,只是正确率极高。因为有可能出题人构造数据使两个数的哈希值相同(也就是哈希冲突)。如果想降低被卡概率,可以改成随机乘数和模数,最好多开一个随机模数进行验证,这样错误概率可以忽略不计,并且目前还没有较为稳定的卡法。
时间复杂度 O(nm)O(nm)O(nm),常数 ≈1\approx 1≈1。
看看能不能当上最优解(
T6
个人难度:橙下
进制转换罢了,直接复制远古代码就行。
时间复杂度 O(logn)O(\log n)O(logn)。