AT1224 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”三个字母的连续子串的长度。
简化题意
有一个由 J
,O
,I
组成的字符串,求一个子串,使得这三个字符出现次数一样。输出子串的长度的最大值。
思路
本题可以用一个前缀和来维护。
令 J=1,O=1145141,I=−1145142,那么就转换成了一个最长的和为 0 的子串。(之所以取 1145141,是应为这个数比较大)。
枚举 i (from 1 to n)。如果当前子串 [1,i] 的和是 0,那么更新答案。然后就判断存储器中有没有答案,如果有,更新,否则就记录当前和。
至于存储器,可以使用 std::map
实现。
时间复杂度为 O(nlogn)。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
char poem[200005];
int qzh,result=0;
map<int,int> mem;
signed main(){
cin>>n;
cin>>(poem+1);
for(int i=1;i<=n;i++){
char nch=poem[i];
switch(nch){
case 'J':
qzh++;
break;
case 'O':
qzh+=1145141;
break;
case 'I':
qzh+=(-1145141-1);
break;
}
if(qzh==0){
result=max(result,i);
}
if(mem[qzh]!=0){
result=max(result,i-mem[qzh]);
}
else {
mem[qzh]=i;
}
}
cout<<result<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步