JOIOJI
Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss]
Description
JOIOJI桑是JOI君的叔叔。“JOIOJI”这个名字是由“J、O、I”三个字母各两个构成的。
最近,JOIOJI桑有了一个孩子。JOIOJI桑想让自己孩子的名字和自己一样由“J、O、I”三个字母构成,并且想让“J、O、I”三个字母的出现次数恰好相同。
JOIOJI桑家有一份祖传的卷轴,上面写着一首长诗,长度为N,由“J、O、I”三个字母组成。JOIOJIさん想用诗中最长的满足要求的连续子串作为孩子的名字。
现在JOIOJI桑将这首长诗交给了你,请你求出诗中最长的、包含同样数目的“J、O、I”三个字母的连续子串。
Input
第一行一个正整数N,代表这首长诗的长度
接下来一行一个长度为N的字符串S,表示这首长诗,保证每个字符都是“J、O、I”三个字母中的一个
Output
输出一行一个正整数,代表最长的包含等数量“J、O、I”三个字母的最长连续子串的长度。如果不存在这样的子串,输出0
Sample Input
10
JOIIJOJOOI
Sample Output
6
HINT
选择“IIJOJO”这个子串,长度为6,包含“J、O、I”三个字母各2个,这是最长的满足要求的子串。
1<=N<=2*10^5
Solution
假装这是个DP吧qwq。
Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cmath> 8 #include<map> 9 using namespace std; 10 typedef long long s64; 11 12 const int ONE = 2e5+5; 13 14 map <pair<int, int>, int> Map; 15 int n; 16 char S[ONE]; 17 int f[ONE][4]; 18 int Ans; 19 20 int get() 21 { 22 int res=1,Q=1;char c; 23 while( (c=getchar())<48 || c>57 ) 24 if(c=='-')Q=-1; 25 res=c-48; 26 while( (c=getchar())>=48 && c<=57 ) 27 res=res*10+c-48; 28 return res*Q; 29 } 30 31 int id(char S) {return S=='J' ? 1:(S=='O' ? 2 : 3);} 32 int main() 33 { 34 n = get(); 35 scanf("%s", S+1); 36 Map[make_pair(0,0)] = 0; 37 for(int i=1; i<=n; i++) 38 { 39 memcpy(f[i], f[i-1], sizeof(f[i-1])); 40 f[i][id(S[i])]++; 41 42 pair<int,int> t = make_pair(f[i][1] - f[i][2], f[i][2] - f[i][3]); 43 if(Map.find(t) == Map.end()) Map[t] = i; 44 else Ans = max(Ans, i - Map[t]); 45 } 46 printf("%d", Ans); 47 }