1 条题解
-
0
问题一:A 的最短子串,不是 B 的子串
思路
要找最短的 A 的子串 且不在 B 的子串集合 中。
- 如果某个长度 ( L ) 的所有 A 的子串都在 B 中出现过,那么长度 ( L ) 就不符合要求。
- 我们从 ( L = 1 ) 开始枚举长度,检查 A 的所有长度为 ( L ) 的子串是否都在 B 中出现过。
- 一旦找到某个长度 ( L ) 下,A 有一个子串在 B 中找不到,答案就是 ( L )。
- 如果所有 A 的子串(直到长度 (|A|))都在 B 中出现过,则输出 -1。
实现方法:
- 对 B 建立后缀自动机(或哈希表存储所有子串),可以快速判断一个串是否 B 的子串。
- 枚举 A 的所有长度 ( L ) 的子串(按长度从小到大),用后缀自动机检查。
- 复杂度 (O(n^2)) 可行(n ≤ 2000)。
问题二:A 的最短子串,不是 B 的子序列
思路
要找最短的 A 的子串 且不是 B 的子序列。
- 子序列匹配与子串匹配不同:一个串 S 是 B 的子序列,意味着可以从 B 中按顺序挑出 S 的每个字符(不必连续)。
- 对固定的子串 S,检查它是否是 B 的子序列:可以用双指针贪心匹配(或预处理序列自动机)。
- 同样从小到大枚举长度 ( L ),检查 A 的所有长度为 ( L ) 的子串,一旦发现某个不是 B 的子序列,就得到答案。
- 因为子序列匹配比子串匹配“更容易满足”,所以这个答案通常比第一问大。
问题三:A 的最短子序列,不是 B 的子串
思路
要找最短的 A 的子序列 且不是 B 的子串。
- 子序列可以不连续,所以我们可以选尽量短的 A 的字符序列,让它不是 B 的任意连续子串。
- 一个常见思路:如果某个子序列长度 = 1,即单个字符 c,那么只要 c 在 B 中出现过(作为子串),它就不符合要求。
- 如果 A 中所有字符都在 B 中出现过,那么看长度 = 2 的 A 的子序列(任意两个字符按顺序),检查它是否是 B 的某个子串。
- 我们可以枚举长度 k 从 1 开始,用 BFS/DP 的方式生成 A 中所有长度为 k 的子序列(去重),检查是否在 B 的子串集合中。
- 一旦找到不在 B 的子串集合中的子序列,k 就是答案。
关键:因为子序列可以不连续,可能很快就能构造出 B 中没有的串。
例如,如果 B 中没有 "ab" 这个子串,那么 A 中只要存在 a 后面有 b,取这两个字符作为子序列 "ab",就满足要求,答案是 2。
问题四:A 的最短子序列,不是 B 的子序列
思路
要找最短的 A 的子序列 且不是 B 的子序列。
- 这是最宽松的“不属于”条件,因为 B 的子序列集合非常大(几乎包含所有按顺序抽取的字符串)。
- 要让它不是 B 的子序列,意味着在 B 中无法按顺序匹配出这个子序列。
- 常用方法:对 B 建立序列自动机
nxt[i][c]表示位置 i 后字符 c 第一次出现的位置。 - 然后我们枚举长度 k 从 1 开始,用 BFS 生成 A 的所有长度 k 的子序列(去重),用序列自动机检查是否能被 B 匹配。
- 一旦发现某个子序列不能被 B 匹配,就得到答案。
性质:这个答案通常比前几个大,因为 B 的子序列集合很大,需要较长的串才能“避开” B 的匹配。
样例分析
输入:
A = aabbcc B = abcabc- 第一问:长度 1 的所有字符 a,b,c 都在 B 中出现过;长度 2 时,A 有子串 "aa",B 中没有 "aa",所以答案是 2。
- 第二问:长度 1,2,3 的所有 A 的子串都能在 B 中按子序列匹配到;长度 4 时,A 有子串 "aabb",它不能成为 B 的子序列(B 中 a 后 b 的数量不够按顺序匹配出 aabb),答案是 4。
- 第三问:A 的子序列 "aa"(取第一个 a 和第三个 a)不是 B 的子串(B 中没有 "aa"),所以答案是 2。
- 第四问:需要更长的子序列才能不是 B 的子序列,例如 "aabb" 在 B 中匹配不了,但 "aabb" 作为子序列长度是 4,答案是 4。
输出:
2 4 2 4
这样,四个问题分别用 后缀自动机(子串判断)、序列自动机(子序列判断)、枚举+去重 BFS 来解决,整体复杂度 (O(n^2)) 可接受。
- 1
信息
- ID
- 4701
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者