你的负担将变成礼物,你受的苦将照亮你的路。
「一本通 2.2 例 1」剪花布条
题目描述
原题来自:HDU 2087
一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?
输入格式
输入数据为多组数据,读取到 #
字符时结束。每组数据仅有一行,为由空格分开的花布条和小饰条。花布条和小饰条都是用可见 ASCII 字符表示的,不会超过 10001000 个字符。
注意:这个 # 应为单个字符。若某字符串开头有 #,不意味着读入结束!
输出格式
对于每组数据,输出一行一个整数,表示能从花纹布中剪出的最多小饰条个数。
样例
样例输入
1 | abcde a3 |
样例输出
1 | 0 |
数据范围与提示
对于全部数据,字符串长度 \leq 1000≤1000。
题解
挺简单的KMP的题。
至于保证不重叠也很简单,匹配成功一个的时候让匹配值=0即可,至于为什么保留前面一个忽略和当前冲突的就不用说了,很简单的贪心思想。
Code:
1 |
|
一本通 2.1 练习 1」Power Strings
题目描述
原题来自:POJ 2406
给定若干个长度 \le 10^6≤106 的字符串,询问每个字符串最多是由多少个相同的子字符串重复连接而成的。如:ababab
则最多有 33 个 ab
连接而成。
输入格式
输入若干行,每行有一个字符串。特别的,字符串可能为 .
即一个半角句号,此时输入结束。
样例
样例输入
1 | abcd |
样例输出
1 | 1 |
数据范围与提示
字符串长度
题解
有点难度的KMP题。对于一个由长度大于1的循环节k次循环组成的字符串,最大相同前后缀必定是k-1个循环节组成的。设循环节长度为L
必要性显然,也就是说最大相同前后缀长度不小于k-1个循环字符串。
考虑假设最大前缀多x位。显然x <= next(L)。
然而这意味着每一个字符向后移动x位依然相同,所以最小循环节是x,与最初假设矛盾。
因此答案是
注意检验
Code:
1 |
|
「一本通 2.2 练习 1」Radio Transmission
题目描述
原题来自:BalticOI 2009
给你一个字符串,它是由某个字符串不断自我连接形成的。但是这个字符串是不确定的,现在只想知道它的最短长度是多少。
输入格式
第一行给出字符串的长度 LL,第二行给出一个字符串,全由小写字母组成。
输出格式
输出最短的长度。
样例
样例输入 1
1 | 8 |
样例输出 1
1 | 3 |
样例说明
对于样例,我们可以利用 abc
不断自我连接得到 abcabcabc
,读入的 cabcabca
是它的子串。
数据范围与提示
对于全部数据,
题解
和上面的一样,从上题证明中我们能够发现最长相同前后缀长度为L,字符串长度为n
那么我们可以把字符串后L位视为前L位平移n-L位,这样的话就相当于循环节是n-L.(除去特殊情况)
本题同理,就像分块一样,字符串只有可能有两个不完整的循环节,位于头尾。
但是中间最少有一个完整的循环节,这样前面不完整和后面不完整可以与中间组合,然后n-next(n)
就是正好一个完整的串。
不怎么会证,画图证明
Code:
1 |
|
「一本通 2.2 练习 4」Censoring
题目描述
原题来自:USACO 2015 Feb. Silver
给出两个字符串 S 和 T,每次从前往后找到 S 的一个子串 A=T 并将其删除,空缺位依次向前补齐,重复上述操作多次,直到 SS 串中不含 TT 串。输出最终的 S 串。
输入格式
第一行包含一个字符串 S,第二行包含一个字符串 T。
输出格式
输出处理后的 SS 串。
样例
样例输入
1 | whatthemomooofun |
样例输出
1 | whatthefun |
数据范围与提示
对于全部数据,
,保证字符串中只出现小写字母。
题解
一道比较有意思的题。
我们只需要开一开脑洞,将母串每个位置成功匹配的数量记录下来,然后删除后跳回删除串的前一个位置,从
继续开始匹配就行了。
时间复杂度分析依然要用到摊还分析的策略:
由于回跳的前提是删除了母串中长度为m的模式串,那么跳后剩下的距离和普通KMP是一样的,所以时间复杂度不变
Code:
1 |
|
「一本通 2.2 练习 3」似乎在梦中见过的样子
原题来自:2014 年湖北省队互测 Week2
「Madoka,不要相信 QB!」伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约。
这是 Modoka 的一个噩梦,也同时是上个轮回中所发生的事。为了使这一次 Madoka 不再与 QB 签订契约,Homura 决定在刚到学校的第一天就解决 QB。然而,QB 也是有许多替身的(但在第八话中的剧情显示它也有可能是无限重生的),不过,意志坚定的 Homura 是不会放弃的——她决定消灭所有可能是 QB 的东西。现在,她已感受到附近的状态,并且把它转化为一个长度为 nn 的字符串交给了学 OI 的你。
现在你从她的话中知道,所有形似于 A+B+AA+B+A 的字串都是 QB 或它的替身,且 |A|\ge k,|B|\ge 1∣A∣≥k,∣B∣≥1 (位置不同其他性质相同的子串算不同子串,位置相同但拆分不同的子串算同一子串),然后你必须尽快告诉 Homura 这个答案——QB 以及它的替身的数量。
注:对于一个字符串 SS,|S|∣S∣ 表示 SS 的长度。
输入格式
第一行一个字符串 SS,第二行一个数 kk。
输出格式
仅一行一个数 \text{ans}ans,表示 QB 以及它的替身的数量。
样例
样例输入 1
1 | aaaaa |
样例输出 1
1 | 6 |
样例输入 2
1 | abcabcabc |
样例输出 2
1 | 8 |
数据范围与提示
对于全部数据,1\le |S|\le 1.5\times 10^4,1\le k\le 1001≤∣S∣≤1.5×104,1≤k≤100,且字符集为所有小写字母。
题解
果然胡策题质量不高。。一道标算复杂度爆炸的题。。。最坏
居然过了。。
Code:
1 |
|
「一本通 2.2 练习 2」OKR-Periods of Words
原题来自:POI 2006
串是有限个小写字符的序列,特别的,一个空序列也可以是一个串。一个串 PP 是串 AA 的前缀,当且仅当存在串 BB,使得 A = PBA=PB。如果 P \not =AP̸=A 并且 PP 不是一个空串,那么我们说 PP 是 AA 的一个 proper 前缀。
定义 QQ 是 AA 的周期,当且仅当 QQ 是 AA 的一个 proper 前缀并且 AA 是 QQQQ 的前缀(不一定要是 proper 前缀)。比如串 abab
和 ababab
都是串 abababa
的周期。串 AA 的最大周期就是它最长的一个周期或者是一个空串(当 AA 没有周期的时候),比如说,ababab
的最大周期是 abab
。串 abc
的最大周期是空串。
给出一个串,求出它所有前缀的最大周期长度之和。
输入格式
第一行一个整数 kk,表示串的长度。
接下来一行表示给出的串。
输出格式
输出一个整数表示它所有前缀的最大周期长度之和。
样例
样例输入
1 | 8 |
样例输出
1 | 24 |
数据范围与提示
对于全部数据,1\lt k\lt 10^61<k<106。
题解
想的挺对,不过不知道一开始有个傻逼细节写错了。。。
简述题意就是对于每个1~i,我们都要求出一个最大前缀(不能一模一样),使得这个前缀倍长后当前的1~i是其前缀(可以一样)。
还是用到KMP中next数组的一个性质来求循环节,上面说过是n-next(n),但是我们希望它最大,于是多跳几次next只要它大于0,并且最后必须保证
就可以加到答案里。
注意倍增优化。
时间复杂度:
Code:
1 |
|
这样一来一本通上的6道题目就全做完了,全部独立AC,还算不错。
鼓捣一下blog