2024.9.7校测
T1
题目描述
有
一个平衡的区间是指,选出这一排青蛙中连续的一段,在区间中每种特征出现的次数是一样的。请问这样平衡区间的最大长度是多少?
输入格式
第一行两个数
接下来
输出格式
一个整数,表示平衡区间的最大长度。
输入样例
7 3
7
6
7
2
1
4
2
输出样例
4
样例解释
数据规模
对于
对于
T2
题目描述
给出一个敏感词
输入格式
第一行一个词
第二行一篇文章
输出格式
输出一行,删减过的文章。
输入样例
abc
aaabcbc
输出样例
a
数据规模
对于
对于
所有字符串均只包括小写字母。
题解
先考虑最朴素的算法,每次用 KMP 找到模式串在文本串中的位置,将它们删掉,讲其它部分拼接起来,重复这个过程直到找不到模式串为止,但这样最坏复杂度为
可以发现,删除一个模式串,将前后拼接起来,这个过程很像栈的操作。于是我们考虑一边进行 KMP,一边将当前字符扔入栈,如果匹配上了,就直接将栈中的这个模式串弹出,这样就可以使复杂度降到
完整代码
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 9;
char a[N], b[N];
int st[N], f[N], g[N], n, m, tot;
int main(){
freopen("sensitive.in", "r", stdin);
freopen("sensitive.out", "w", stdout);
scanf("%s%s", b + 1, a + 1);
n = strlen(a + 1);
m = strlen(b + 1);
for(int i = 2, k = 0; i <= m; i++){
while(k && b[k + 1] != b[i])
k = f[k];
if(b[k + 1] == b[i])
k++;
f[i] = k;
}
for(int i = 1, k = 0; i <= n; i++){
while(k && b[k + 1] != a[i])
k = f[k];
if(b[k + 1] == a[i])
k++;
g[i] = k;
st[++tot] = i;
if(k == m){
tot -= k;
k = g[st[tot]];
}
}
for(int i = 1; i <= tot; i++)
printf("%c", a[st[i]]);
return 0;
}
T3
题目描述
在网络上,尤其是网络游戏中,一些人出口成脏,影响网络环境。现在给出 *
号省略表示。
输入格式
第一行一个数
接下来
接下来一行,表示文章
输出格式
输出净化后的文章。
输入样例
3
trump
ri
o
Donald John Trump (born June 14, 1946) is an American businessman,television personality, author, politician, and the RepublicanParty nominee for President of the United States in the 2016 election. He is chairman of The Trump Organization, which is theprincipal holding company for his real estate ventures and otherbusiness interests.
输出样例
D*nald J*hn ***** (b*rn June 14, 1946) is an Ame**can businessman,televisi*n pers*nality, auth*r, p*litician, and the RepublicanParty n*minee f*r President *f the United States in the 2016 electi*n. He is chairman *f The ***** *rganizati*n, which is thep**ncipal h*lding c*mpany f*r his real estate ventures and *therbusiness interests.
数据规模
设
对于
对于
关键词只包括小写字母,不区分大小写。
题解
此问题是典型的多模式串匹配问题,考虑使用 AC 自动机。
为了方便记录哪些字母要被替换成 *
,我们在将模式串插入字典树时在每个串的末尾记录一下这个串的长度,在查询时,每跳一个 fail 指针就将这个串所在的区间(*
,否则输出该字符
完整代码
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 9;
struct Node{
int son[26], end, fail, len;
} t[N];
int cnt = 1;
void insert(char *s){
int now = 0;
for(int i = 0; s[i]; i++){
int ch = s[i] - 'a';
if(t[now].son[ch] == 0)
t[now].son[ch] = cnt++;
now = t[now].son[ch];
}
t[now].end++;
t[now].len = strlen(s);
}
void getFail(){
queue <int> q;
for(int i = 0; i < 26; i++)
if(t[0].son[i])
q.push(t[0].son[i]);
while(!q.empty()){
int now = q.front();
q.pop();
for(int i = 0; i < 26; i++)
if(t[now].son[i]){
t[t[now].son[i]].fail = t[t[now].fail].son[i];
q.push(t[now].son[i]);
} else
t[now].son[i] = t[t[now].fail].son[i];
}
}
int flag[N];
int query(char *s){
int ans = 0;
int now = 0;
for(int i = 0; s[i]; i++){
int ch = s[i] - 'a';
now = t[now].son[ch];
int tmp = now;
while(tmp){
ans += t[tmp].end;
flag[i + 1]--;
flag[i - t[tmp].len + 1]++;
tmp = t[tmp].fail;
}
}
return ans;
}
int n;
char tmp[N];
string s;
int main(){
freopen("cleanse.in", "r", stdin);
freopen("cleanse.out", "w", stdout);
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%s", tmp);
insert(tmp);
}
getchar();
getline(cin, s);
getFail();
int len = s.length();
for(int i = 0; i < len; i++)
if(s[i] >= 'A' && s[i] <= 'Z')
tmp[i] = s[i] - 'A' + 'a';
else
tmp[i] = s[i];
int ans = query(tmp);
for(int i = 1; i < len; i++)
flag[i] += flag[i - 1];
for(int i = 0; i < len; i++)
if(flag[i])
printf("*");
else
printf("%c", s[i]);
return 0;
}
T4
题目描述
给出一个串 a
的不同的子串有多少个?
输入格式
第一行一个串,表示
输出格式
一个整数,表示包含字母 a
的不同的子串的个数。
输入样例1
abc
输出样例1
3
输入样例2
aaa
输出样例2
3
数据规模
对于
对于
本文来自博客园,作者:JPGOJCZX,转载请注明原文链接:https://www.cnblogs.com/JPGOJCZX/p/18422882
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】