1. 问题背景与核心概念解析
这道来自Codeforces 1029A的编程题目,考察的是字符串处理中一个经典概念——最长相等真前后缀(也称为字符串的失败函数或部分匹配表)。我们先拆解题目中的几个关键术语:
真前后缀指的是既是字符串前缀又是后缀,且长度严格小于字符串本身长度的子串。例如字符串"abab"的真前后缀有:
- 长度为3:"aba"(不是后缀)、"bab"(不是前缀)
- 长度为2:"ab"(既是前缀也是后缀)
- 长度为1:"a"(既是前缀也是后缀)
最长相等真前后缀就是这个集合中最长的那个,上例中就是长度为2的"ab"。这个概念在KMP字符串匹配算法中扮演着关键角色。
题目要求我们构造一个最短的新字符串,使得原字符串t是这个新字符串的子串,并且新字符串由k个t拼接而成。例如当t="abab"且k=2时,最优解是"ababab"(只需6个字符而非8个)。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法思路与数学证明
2.1 关键观察
通过分析示例可以发现,当原字符串存在非空的最长相等真前后缀时,我们可以利用重叠部分来缩短构造结果。具体规律:
- 设原字符串t长度为n
- 设其最长相等真前后缀长度为l
- 则最短构造结果为:t + (k-1)次重复t的后(n-l)个字符
正确性证明:
- 每次重叠部分恰好是最长相等真前后缀
- 保证了新字符串确实由k个t组成
- 通过数学归纳法可证明这是最短构造
2.2 求解最长相等真前后缀
这是问题的核心步骤,可以采用KMP算法中的预处理方法:
python复制def compute_lps(t):
lps = [0] * len(t)
length = 0
for i in range(1, len(t)):
while length > 0 and t[i] != t[length]:
length = lps[length-1]
if t[i] == t[length]:
length += 1
lps[i] = length
return lps[-1]
这个O(n)时间的算法会返回最长相等真前后缀的长度。例如:
- "ab
