题解:CF1941C(C. Rudolf and the Ugly String)
题目翻译:给定一个字符串,请你求出最少需要删除几个字符才能使得该字符串内不存在 map
和 pie
。
我们可以先在该字符串内找到所有的子串 mapie
,并删除中间的 p
,这样可以用删除
1
1
1 个字符的代价干掉一个 map
和一个 pie
(共两个)。显然这样的字符串不会重叠出现。
之后,剩下的所有 map
和 pie
都不存在重叠。这时,我们可以找到所有的子串 map
和 子串 pie
,并删去中间的 a
或 i
,这样我们可以用删除
1
1
1 个字符的代价干掉一个 map
或一个 pie
(共一个)。
显然,这样选是最优的。
我们该如何实现呢?我们不能真的用字符串去模拟删除操作,但是我们可以通过枚举形如 mapie
、map
和 pie
的子串的数量得出。具体的,记 map
和 pie
的总数量为
a
n
s
ans
ans,mapie
的数量为
a
n
s
2
ans2
ans2 ,正常情况下答案应该为
a
n
s
+
a
n
s
2
ans+ans2
ans+ans2,但由于每出现一个 mapie
就会对应的出现一组 map
和 pie
,而我们并没有进行去重,所以每个 mapie
在计算
a
n
s
2
ans2
ans2 之前就已经被统计了两次,所以应该减去一次,即最终的答案应该是
a
n
s
−
a
n
s
2
ans-ans2
ans−ans2。
代码:
#include<bits/stdc++.h>
using namespace std;
int t;
string x;
int main(){
scanf("%d",&t);
while(t--){
cin>>x>>x;
int l=x.size(),ans=0,ans2=0;
for(int i=1;i<l-1;i++){
if(x[i-1]=='m'&&x[i]=='a'&&x[i+1]=='p'){
ans++;
}
if(x[i-1]=='p'&&x[i]=='i'&&x[i+1]=='e'){
ans++;
}
if(i!=1&&i!=l-2){
if(x[i-2]=='m'&&x[i-1]=='a'&&x[i]=='p'&&x[i+1]=='i'&&x[i+2]=='e'){
ans2++;
}
}
}
printf("%d\n",ans-ans2);
}
return 0;
}