CF1200E Compress Words
洛谷题目传送门
分析
模拟过程是先是前两个单词合并,合并之后的句子再接着和第三个单词合并这样子
所以过程中肯定是要开个 串不断去进行合并预处理和答案累加
合并单词 和单词 时,要得到最大的长度 ,消除 的后缀 或者消除 的前缀,
但是 是答案串,直接消除 的前缀更好。
接下来要确定 的求法,如果我们把 串放在 串前面,那么要消除的这个最大长度,
不正好就是就是 吗
再仔细考虑,匹配的最大长度肯定不会超过 串的长度,为了避免 串过长,我们可以删掉它前面大于 串长度的部分
所以思路确定下来:
1.先把 串放在处理后的 串前面,中间用特殊字符分开;
2.对合成后的串求next数组,得到 为最大匹配长度(即 要消除的长度)
3.把 前面消除后加到 串里
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define rg register
inline int read(){
rg int x = 0, f = 1;
rg char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x * f;
}
const int N = 1e6 + 1;
int n;
int net[N];
int prenext(string a){
net[0] = 0;
int len = a.length();
for (int i = 1; i < len; ++i){
int j = net[i - 1];
while (j && a[j] != a[i]) j = net[j - 1];
if (a[j] == a[i]) net[i] = j + 1;
else net[i] = 0;
}
return net[len - 1];
}
inline void doit(){
cin >> n;
string b, ans;
cin >> ans;
for (int i(2); i <= n; ++i){
cin >> b;
int l = min(b.size(), ans.size());
string a = b + "#" + ans.substr(ans.size() - l, l);
b.erase(0, prenext(a));
ans += b;
}
cout << ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
//freopen("in.txt", "r", stdin);
doit();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)