问题:
一个长度为 n 的字符串 s,其中仅包含 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符。
如果四种字符在字符串中出现次数均为 n/4,则其为一个平衡字符串。
现可以将 s 中连续的一段子串替换成相同长度的只包含那四个字符的任意字符串,使其变为一个平衡字符串,问替换子串的最小长度?
如果 s 已经平衡则输出0。## input:
第1行:一个数n
第2行到第n+1行:数wi
第n+2行到第2n+1行:矩阵即pij矩阵
input:
一行字符表示给定的字符串s
output:
一个整数表示答案
sample:
Input
QWER
Output
0
Input
QQWE
Output
1
Input
QQQW
Output
2
Input
QQQQ
Output
3
题解:
1.本实验采用的是尺取法,尺取法,顾名思义就是使用l,r维护取出区间的左右端点,通过改变l,r的值,将区间的范围进行更改。
2.对于本题,我们使用尺取法进行选取可替换的区间,如果l,r之间的元素满足条件。此时如果我们将r右移,那么该区间也一定满足条件,对答案没有贡献,如果我们将l右移,那么区间缩小,对答案有可能有贡献,这样我们就可以确定思路。
3.那么如何进行判断是否满足条件。我们将不包括我们尺取的区间中q,w,e,r的数量统计下来,之后将l,r区间之中的元素进行替换,替换完成之后使q,w,e,r的数量相等,查看剩余可替换的位置时候为4的倍数,如果为四的倍数,那么我们就认为满足条件。
完整代码:
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
using namespace std;
map<char, int> mp1;
string s;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
cin>>s;
int ans;
int l=0;
int r=0;
int length=s.length();
mp1['Q']=1;
mp1['W']=2;
mp1['E']=3;
mp1['R']=4;
int count[5]={0};
for(int i=0;i<length;i++)
{
count[mp1[s[i]]]++;
}
if(count[1]==length/4&&count[2]==length/4&&count[3]==length/4&&count[4]==length/4)
{
cout<<0<<endl;
return 0;
}
count[mp1[s[r]]]--;
while(r<length)
{
int ok=r-l+1;
int maxcount=max(max(count[1],count[2]),max(count[3],count[4]));
int no=ok-(4*maxcount-count[1]-count[2]-count[3]-count[4]);
if(no>=0&&no%4==0)
{
ans=min(ans,r-l+1);
count[mp1[s[l]]]++;
l++;
}
else
{
r++;
count[mp1[s[r]]]--;
}
}
cout<<ans<<endl;
return 0;
}
反思:
本实验对条件的判断使用代码表示比较繁琐,一定不要搞错。