1 条题解
-
0
题目 C. Saraga 详细题解
问题重述
给定两个字符串 和 ,要求构造一个最短的字符串 ,使得存在至少两种不同的方式将 分割成两个非空子串 和 (即 ),其中 是 的前缀, 是 的后缀。若不存在则输出 。
关键转化
对于任意一种分割方式,设分割点位于第 个字符之后,即 是 的前缀, 是 的后缀。令 (可能为空?但要求 非空,所以 ; 非空,所以 ;而 可以为空,但后续需要 非空?实际上我们后面会要求 非空,但这里先保留)。再令 (单个字符),,则:
- 是 的前缀,
- 是 的后缀,且 也是 的后缀(因为 是 加上前面一个字符,不一定是后缀?注意, 实际上是 从 开始的后缀,而 是从 开始,所以 不一定是 的后缀。但我们可以换一种方式:另一种常见的分解是 ,其中 是 的后缀。所以实际上,对于一个分割点 ,我们可以定义三元组 满足:
- ,
- 是 的前缀,
- 是 的后缀,
- (因为 恰好是分割点处的单个字符)。
因此每一种分割方式都对应一个单字符 。
化简到
题目要求至少两种不同的分割方式,即存在两个不同的单字符位置 和 (可能相同字符但位置不同),使得相应的条件成立。可以证明(见标程推导),任何有趣的缩写都可以通过不断将 的最后一个字符移到 前面,最终得到一个 的表示,且该表示仍然具有至少两种分割方式。因此,我们只需要考虑 的情况。
构造方法
对于任意一个字符 ,假设存在一个 的前缀 (长度 )以 结尾,并且存在一个 的后缀 (长度 )以 开头。那么构造
其中 是 的前缀(长度为 ), 是 的后缀(长度为 ),则 的长度为 。于是 。
这个 自动具有两种不同的分割方式:
- 分割点在 的末尾:( 的前缀),( 的后缀,因为 是后缀,去掉第一个字符 后 仍是后缀)。
- 分割点在 去掉最后一个字符后的位置:设 ,则 是 的前缀(长度 ),且 是 的后缀,于是 ,,两者非空且满足条件。
因此,只要存在这样的 ,就能构造出一个有趣的缩写。为了得到最短的 ,我们只需对每个 ,取 中最短的以 结尾的前缀(即最小的 使得 ),以及 中最短的以 开头的后缀(即最小的 使得 的倒数第 个字符为 ),然后计算长度 ,取所有 中的最小值即可。
算法步骤
- 初始化两个数组 和 为无穷大。
- 遍历 (下标从 开始),对于 到 ,令 ,更新 。
- 遍历 ,对于 到 (即从倒数第二个字符向前),令 ,后缀长度 (),更新 。
- 枚举 到 ,若 和 均非无穷,则候选长度 ,记录最小 及对应的 。
- 若无任何候选,输出 ;否则,输出 $S[1..\text{pref}[c]] + T[|T|-\text{suf}[c]+2 .. |T|]$(即 的前 个字符拼接 的最后 个字符)。
复杂度分析
- 预处理 。
- 枚举 个字母 。
- 总时间复杂度 ,满足 的要求。
边界情况
- 如果 或 ,则无法找到长度 的前缀或后缀,输出 。
- 注意字符串下标从 开始时的实现细节。
参考代码(C++)
#include <bits/stdc++.h> using namespace std; int main() { string S, T; cin >> S >> T; int n = S.size(), m = T.size(); const int INF = 1e9; vector<int> pref(26, INF), suf(26, INF); // 最短前缀(长度>=2)以某字母结尾 for (int i = 1; i < n; ++i) { // i是索引,对应长度i+1 int c = S[i] - 'a'; pref[c] = min(pref[c], i+1); // 长度 = i+1 } // 最短后缀(长度>=2)以某字母开头 for (int j = m-2; j >= 0; --j) { int c = T[j] - 'a'; int len = m - j; // 从j到末尾的长度 suf[c] = min(suf[c], len); } int best_len = INF; char best_c = -1; for (int c = 0; c < 26; ++c) { if (pref[c] != INF && suf[c] != INF) { int len = pref[c] + suf[c] - 1; if (len < best_len) { best_len = len; best_c = c; } } } if (best_c == -1) { cout << -1 << endl; } else { string ans = S.substr(0, pref[best_c]) + T.substr(m - (suf[best_c] - 1)); cout << ans << endl; } return 0; }
- 1
信息
- ID
- 7154
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者