CF25E Test 题解
考虑枚举三个字符串的全排列,设为
分类讨论:
-
若
是 的子串:- 若
是 的子串,最短的长度为 的长度。 - 否则找到
的最长前缀,满足其是 的后缀。
- 若
-
否则:
- 找到
的最长前缀,满足其是 的后缀。 - 设找到后拼起来的字符串为
。讨论 与 的关系即可。
- 找到
可以 KMP,也可以哈希。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
// 12323
const int N = 5e5 + 5;
using ull = unsigned long long;
string s[4];
int ans = 2e9;
ull powe[N], hash1[N], hash2[N], hash3[N], hash4[N];
int getans()
{
hash1[0] = s[1][0] - 'a' + 1;
hash2[0] = s[2][0] - 'a' + 1;
hash3[0] = s[3][0] - 'a' + 1;
for (int i = 1; i < s[1].size(); i++)
{
hash1[i] = hash1[i - 1] * 337 + (s[1][i] - 'a' + 1);
}
for (int i = 1; i < s[2].size(); i++)
{
hash2[i] = hash2[i - 1] * 337 + (s[2][i] - 'a' + 1);
}
for (int i = 1; i < s[3].size(); i++)
{
hash3[i] = hash3[i - 1] * 337 + (s[3][i] - 'a' + 1);
}
ull h1 = hash1[s[1].size() - 1], h2 = hash2[s[2].size() - 1], h3 = hash3[s[3].size() - 1];
bool flag = 0;
for (int i = 0; i + s[2].size() - 1 < s[1].size(); i++)
{
int l = i, r = i + s[2].size() - 1;
ull subhash = hash1[r] - (l == 0 ? 0 : hash1[l - 1] * powe[r - l + 1]);
if (subhash == h2)
{
flag = 1;
break;
}
}
if (flag)
{
bool flag2 = 0;
for (int i = 0; i + s[3].size() - 1 < s[1].size(); i++)
{
int l = i, r = i + s[3].size() - 1;
ull subhash = hash1[r] - (l == 0 ? 0 : hash1[l - 1] * powe[r - l + 1]);
if (subhash == h3)
{
flag2 = 1;
break;
}
}
if (flag2) return s[1].size();
int res = s[1].size() + s[3].size();
for (int i = 1; i <= min(s[1].size(), s[3].size()); i++)
{
int l1 = 0, r1 = i - 1;
int l2 = s[1].size() - i, r2 = s[1].size() - 1;
ull hs1 = hash3[r1];
ull hs2 = hash1[r2] - (l2 == 0 ? 0 : hash1[l2 - 1] * powe[r2 - l2 + 1]);
if (hs1 == hs2) res = min(res, (int)(s[1].size() + s[3].size() - i));
}
return res;
}
else
{
string mn = s[1] + s[2];
int res = s[1].size() + s[2].size();
int p = 0;
for (int i = 1; i <= min(s[1].size(), s[2].size()); i++)
{
int l1 = 0, r1 = i - 1;
int l2 = s[1].size() - i, r2 = s[1].size() - 1;
ull hs1 = hash2[r1];
ull hs2 = hash1[r2] - (l2 == 0 ? 0 : hash1[l2 - 1] * powe[r2 - l2 + 1]);
if (hs1 == hs2)
{
if ((int)(s[1].size() + s[2].size() - i) < res)
{
res = (s[1].size() + s[2].size() - i);
p = i;
}
}
}
if (p)
{
mn = s[1].substr(0, s[1].size() - p) + s[2];
}
hash4[0] = mn[0] - 'a' + 1;
for (int i = 1; i < mn.size(); i++)
{
hash4[i] = hash4[i - 1] * 337 + (mn[i] - 'a' + 1);
}
res = mn.size() + s[3].size();
for (int i = 1; i <= min(mn.size(), s[3].size()); i++)
{
int l1 = 0, r1 = i - 1;
int l2 = mn.size() - i, r2 = mn.size() - 1;
ull hs1 = hash3[r1];
ull hs2 = hash4[r2] - (l2 == 0 ? 0 : hash4[l2 - 1] * powe[r2 - l2 + 1]);
if (hs1 == hs2)
{
res = min(res, (int)(mn.size() + s[3].size() - i));
}
}
return res;
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(nullptr), cout.tie(nullptr);
powe[0] = 1;
for (int i = 1; i < N; i++)
{
powe[i] = powe[i - 1] * 337;
}
cin >> s[1] >> s[2] >> s[3];
sort(s + 1, s + 4);
int res = 1e9;
do
{
res = min(res, getans());
} while (next_permutation(s + 1, s + 4));
cout << res << "\n";
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现