题解:P15029 [UOI 2021 II Stage] 酷子串
liuyingszy · · 题解
我们一定要学会看算法标签。
题意简述
给定一个长度为
思路分析
对于一个长度为
那么最少需要修改的次数为
实现方式
注意到算法标签写了双指针。
我们维护
使用两个计数器数组分别记录区间中奇数位置和偶数位置的字符出现次数,不断向右移动右指针
对于每个区间,计算需要的最小修改次数,如果最小修改次数
移动左指针时,需要更新计数器,并且要注意区间内奇偶位置会发生翻转。
每次找到一个可行区间后,更新最大长度。
代码
#include<bits/stdc++.h>
using namespace std;
char s[5002026];
int s1[5002026];
int cnt1[26],cnt2[26];
int l,ans=-1;
int main(){
int n,k;
scanf("%d%d",&n,&k);
scanf("%s",s);
//转换为数字方便计算
for(int i=0;i<n;++i){
s1[i]=s[i]-'a';
}
for (int r=0;r<n;++r){
//统计次数
if((r-l)%2==0){
cnt1[s1[r]]++;
}else{
cnt2[s1[r]]++;
}
//收缩左边界
while(l<=r){
int max1=0,max2=0;
for (int i=0;i<26;++i){
if(cnt1[i]>max1) max1=cnt1[i];
if(cnt2[i]>max2) max2=cnt2[i];
}
int len=r-l+1;
if(max1+max2>=len-k){
break;
}
cnt1[s1[l]]--;
swap(cnt1,cnt2);//交换奇偶位置
l++;
}
ans=max(ans,r-l+1);
}
printf("%d",ans);//愉快输出
return 0;
}
完结撒花QwQ。