(\)
(Description)
给出一个仅由(J,O,I)三个字母构成的长度为(N)的字符串,定义一段字符串合法,为该字符串三类字符个数相同,求最长合法子串长度。
- (Nin [0,2 imes 10^5])
(\)
(Solution)
- 判断区间和为(0)的时候,我们是通过前缀和相同判断的,此题可以参考同样的方法。
- 注意到有影响区间和是否相同的,是三个字符间的差值,所以记录到每一个位置(O,I)分别对(J)个数的差,并记录该情况的上一位置即可。注意到状态量最差是(N^2)的并开不下,用(map<pair<int,int>,int>)就好。
(\)
(Code)
#include<map>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 200010
#define R register
#define gc getchar
using namespace std;
char c;
int n,ans,cnt[3];
map<pair<int,int>,int> m;
inline int calc(char c){return (c=='J'?0:(c=='O'?1:2));}
int main(){
c=gc();
while(!isdigit(c)) c=gc();
while(isdigit(c)){n=(n<<1)+(n<<3)+(c^48);c=gc();}
while(!isupper(c)) c=gc();
++cnt[calc(c)];
m[make_pair(0,0)]=0;
m[make_pair(cnt[1]-cnt[0],cnt[2]-cnt[0])]=1;
for(R int i=2;i<=n;++i){
++cnt[calc(gc())];
int nowx=cnt[1]-cnt[0];
int nowy=cnt[2]-cnt[0];
if(nowx==0&&nowy==0) ans=max(ans,i);
else{
if(m[make_pair(nowx,nowy)]!=0) ans=max(ans,i-m[make_pair(nowx,nowy)]);
else m[make_pair(nowx,nowy)]=i;
}
}
printf("%d
",ans);
return 0;
}