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
JOIIJOJOOI
Sample Output
6
HINT
选择“IIJOJO”这个子串,长度为6,包含“J、O、I”三个字母各2个,这是最长的满足要求的子串。
1<=N<=2*10^5
Source
JOI 2013~2014 春季training合宿 竞技3 By PoPoQQQ
介绍一种懒人方法。。
设JOI分别出现x,y,z次
用map记录pair(y-x,z-x)
然后相同说明中间一段可取
求出最大值即可
手写hash可以少个log
#include<map>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct save
{
int x,y;
bool operator <(save xx) const
{
return x<xx.x||x==xx.x&y<xx.y;
}
};
save x;
map<save,int> M;
map<save,int>::iterator it;
int main()
{
int n;
scanf("%d",&n);
string xx;
cin>>xx;
int ans=0;
int i;
M[x]=0;
for(i=1;i<=n;i++)
{
if(xx[i-1]=='J')
{
x.x--;
x.y--;
}
if(xx[i-1]=='O')
x.x++;
if(xx[i-1]=='I')
x.y++;
it=M.find(x);
if(it==M.end())
M[x]=i;
else
{
int xt=M[x];
ans=max(ans,i-xt);
}
}
printf("%d\n",ans);
return 0;
}