题意介绍
一个长度为 n 的字符串 s,其中仅包含 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符。如果四种字符在字符串中出现次数均为 n/4,则其为一个平衡字符串。现可以将 s 中连续的一段子串替换成相同长度的只包含那四个字符的任意字符串,使其变为一个平衡字符串,问替换子串的最小长度?
题意分析
尺取法。用sum1,sum2,sum3,sum4分别标记四个字母在s中出现的次数,如果彼此相等则已经是平衡的。否则计算不在[L,R]区间内的四个字母的个数,然后通过改变区间内的字母使得他们的个数彼此相等,如果此时区间内剩余没有改变的字母个数为4的倍数,说明该区间符合条件,L++,否则R++。
通过代码
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
string c;
int L, R;
int mn = 100000;
int sum1, sum2, sum3, sum4;
int main() {
ios::sync_with_stdio(false);
cin >> c;
int count = c.length();
L = 0,R=0;
for (int i = 0; i < count; i++) {
switch (c[i]) {
case 'Q':sum1++;
break;
case 'W':sum2++;
break;
case 'E':sum3++;
break;
case 'R':sum4++;
break;
}
}
if (sum1 == sum2 && sum2 == sum3 && sum3== sum4) cout << 0 << endl;
else {
if (c[0] == 'Q') sum1--;
if (c[0] == 'W') sum2--;
if (c[0] == 'E') sum3--;
if (c[0] == 'R') sum4--;
while (R < count) {
int mx = max(sum1, max(sum2, max(sum3, sum4)));
int total = R - L + 1;
//cout << R << " " << L << " " << total << endl;
int free = total - (mx - sum1) - (mx - sum2) - (mx - sum3) - (mx - sum4);
if (free>=0 && free % 4 == 0) {
mn = min(mn, total);
if (c[L] == 'Q') sum1++;
if (c[L] == 'W') sum2++;
if (c[L] == 'E') sum3++;
if (c[L] == 'R') sum4++;
L++;
}
else {
R++;
if (c[R] == 'Q') sum1--;
if (c[R] == 'W') sum2--;
if (c[R] == 'E') sum3--;
if (c[R] == 'R') sum4--;
}
}
cout << mn << endl;
}
}