JOIOJI

题目描述:

JOIOJI桑是JOI君的叔叔。“JOIOJI”这个名字是由“J、O、I”三个字母各两个构成的。
最近,JOIOJI桑有了一个孩子。JOIOJI桑想让自己孩子的名字和自己一样由“J、O、I”三个字母构成,并且想让“J、O、I”三个字母的出现次数恰好相同。
JOIOJI桑家有一份祖传的卷轴,上面写着一首长诗,长度为N,由“J、O、I”三个字母组成。JOIOJIさん想用诗中最长的满足要求的连续子串作为孩子的名字。
现在JOIOJI桑将这首长诗交给了你,请你求出诗中最长的、包含同样数目的“J、O、I”三个字母的连续子串。

输入格式:

第一行一个正整数N,代表这首长诗的长度
接下来一行一个长度为N的字符串S,表示这首长诗,保证每个字符都是“J、 O、I”三个字母中的一个

输出格式:

输出一行一个正整数,代表最长的包含等数量“J、O、I”三个字母的最长连续子串的长度。如果不存在这样的子串,输出0。

样例输入:

10
JOIIJOJOOI

样例输出:

6	

数据范围与提示:

选择“IIJOJO”这个子串,长度为6,包含“J、O、I”三个字母各2个,这是最长的满足要求的子串。

1<=N<=2*10^5

思路:

一道简单的模拟题,最后一个排序,用ans记录最长的字符串,

如果三个字母出现的次数相同就输出最长的那个字符串

代码:

#include <cstdio>
#include <algorithm>
using namespace std;
const int M = 200010;
int J,O,I,N;
char s[M];
struct node
{
    
    
	int x,y,id;
	bool operator == (const node &z)
	const
	{
    
    
		return x==z.x&&y==z.y;
	}
	bool operator < (const node &z)
	const
	{
    
    
		return x!=z.x?x<z.x:(y!=z.y?y<z.y:id<z.id);
	}
}p[M];
int main()
{
    
    
	scanf("%d%s",&N,s+1);
	for(int i = 1 ; i <= N ; i++)
	{
    
    
		if(s[i] == 'J')J++;
		if(s[i] == 'O')O++;
		if(s[i] == 'I')I++;
		p[i] = (node){
    
    J-O,I-O,i};
	}
	sort(p,p+1+N);
	int ans = 0 , last = 0 ;
	for(int i = 1 ;i <= N ; i++)
	{
    
    
		if(p[i]==p[i-1])ans = max(ans,p[i].id - p[last].id);
		else last = i;
	}
	printf("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/C202207LYX/article/details/107849626