2025牛客寒假算法基础集训营第三场 C 题
C-智乃的Notepad(Easy version)
题意:
给定 n 个字符串,问最少敲击多少次键盘,才能使得每个字符串都在屏幕上显示过。
- 字符串在屏幕上有效显示,当且仅当屏幕上只有该字符串
- 敲击键盘意思为从键盘上输入 26 个字母以及删除键
思路:
题目明显涉及到字符串前缀,那么就会联想到字典树,可在草稿纸上用样例创建一颗字典树,有利于理解。
最优解是留下最长的字符串,就是屏幕上最终显示最长的字符串;
假设所有的字符串都在屏幕上输入并且被删除,即求和:s[i].size()*2,这就是最原来的结果,计为 sum,通过排序后,可以计算相邻字符串的公共前缀,这些前缀是可以被多次使用的,所以答案要减去 lcp(s[i-1], s[i]),最后最长的字符串不用删了,所以减去 max(s[i].size())。
- ans = (总的字符串长度 - 排序后相邻字符串的lcp)*2 - 最长的字符串长度
如果某些字符串前缀相同,那么前缀只消耗了两次敲击数,但是 sum 加的时候每一个字符串的前缀都计算在里面,所以每两个相邻的字符串都要减去 lcp2,2 是因为 sum 之前加的是 2 倍;对于最长的字符串,只需要消耗一次敲击数,而 sum 计算了两次,所以需要减掉一次。
注意 (sum - lcp)*2 减的是非最长字符串的前缀,lcp 只会计算 n-1 次,会剩下一次没减,可以理解为剩下的那个字符串就是最长的字符串,由于每一个字符串(一共 n 个)计算时都消耗了两次敲击数,所以最后最长的字符串需要减,就不用这么多敲击数,最后最长的字符串不需要删除。
// https://ac.nowcoder.com/acm/contest/95335/C
// ans = (总的字符串长度 - 排序后相邻字符串的lcp)*2 - 最长的字符串长度
#include <bits/stdc++.h>
using namespace std;
// #define int long long
const int MOD = 1e9 + 7;
int t, n, m;
int lcp(const string &a, const string &b) // 最长公共前缀
{
int i = 0;
while (i < a.size() && i < b.size() && a[i] == b[i])
i++;
return i;
}
void solve()
{
cin >> n >> m;
vector<string> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
int l, r;
cin >> l >> r;
sort(a.begin(), a.end());
int sum = a[0].size() * 2, len = 0, maxl = a[0].size();
for (int i = 1; i < n; i++)
{
sum += a[i].size() * 2;
len += lcp(a[i - 1], a[i]) * 2;
maxl = max(maxl, (int)a[i].size());
}
cout << sum - len - maxl << "\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
/*
6 1
wwww
nowcoder
nowccoder
nowdays
coder
days
1 6
51
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现