问题描述:
一个长度为 n 的字符串 s,其中仅包含 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符。
如果四种字符在字符串中出现次数均为 n/4,则其为一个平衡字符串。
现可以将 s 中连续的一段子串替换成相同长度的只包含那四个字符的任意字符串,使其变为一个平衡字符串,问替换子串的最小长度?
如果 s 已经平衡则输出0。
解题思路:
依题意,字符串最后要达到平衡的状态,字符串个数为4N,故每个字母数目应该是N,每个字母都要向最多字母数看齐,故不在’改变区间’内的最大字母数一定不能超过N,只要满足这个条件,且左指针小于等于左指针l就可右移,不满足条件时,r右移。
Input:
一行字符表示给定的字符串s。
Output:
一个整数表示答案。
输入输出示例:
Input
QWER
Output
0
Input
QQWE
Output
1
Input
QQQW
Output
2
Input
QQQQ
Output
3
实验代码:
#include<iostream>
#include<string>
using namespace std;
string s;
char a[4]={'Q','W','E','R'};
int sou(char c)
{
for(int i=0;i<4;i++)
if(a[i]==c)
return i;
return -1;
}
int ans,tj[4];
void pingheng(int n)
{
int m=n/4;
for(int i=0;i<n;i++)
tj[sou(s[i])]++;
if(tj[0]==tj[1]&&tj[1]==tj[2]&&tj[2]==tj[3])
return;
int l=0,r=0,maxn;
tj[sou(s[0])]--;
ans=n;
int len;
while(1)
{
maxn=0;
for(int i=0;i<4;i++)
if(tj[i]>maxn)
maxn=tj[i];
if(maxn<=m&&l<=r)
{
len=r-l+1;
if(len<ans)
ans=len;
tj[sou(s[l])]++;
l++;
}
else
{
if(r==n-1)
break;
r++;
tj[sou(s[r])]--;
}
}
}
int main(void)
{
cin>>s;
int n=s.length();
pingheng(n);
cout<<ans<<endl;
return 0;
}