BZOJ 4236: JOIOJI

Description

给出一个字符串,只包含3个字母,询问最长的一个子串,3个字母出现次数相同.

Sol

map.

如果一个子串满足条件,那么它端点处的三个字母的个数两两差值都是一样的,直接存个状态强行上map.

注意要加入一个初始状态.

Code

#include<cstdio>
#include<map>
#include<iostream>
using namespace std;
 
const int N = 200005;
 
struct S{ int a[3]; }g[N];
bool operator < (const S &x,const S &y){ return x.a[0]==y.a[0] ? (x.a[1] == y.a[1] ? x.a[2] < y.a[2] : x.a[1] < y.a[1]) : x.a[0] < y.a[0]; }
int n,ans,s[N];
map<S,int> mp;
 
inline int idx(char ch){ if(ch == 'J') return 0;else if(ch == 'O') return 1;else return 2; }
int main(){
    scanf("%d",&n);
    char ch=getchar();while(ch>'Z' || ch<'A') ch=getchar();
    for(int i=1;i<=n;i++) s[i]=idx(ch),ch=getchar(),g[i]=g[i-1],g[i].a[s[i]]++;
    S tmp;tmp.a[0]=tmp.a[1]=tmp.a[2]=0;
    mp[tmp]=0;
    for(int i=1;i<=n;i++){
        S tmp;
        tmp.a[0] = g[i].a[0]-g[i].a[1],tmp.a[1] = g[i].a[0]-g[i].a[2],tmp.a[2] = g[i].a[1]-g[i].a[2];
        if(mp.count(tmp)) ans=max(ans,i-mp[tmp]);
        else mp[tmp]=i;
    }return cout<<ans<<endl,0;
}

  

posted @ 2016-10-26 19:07  北北北北屿  阅读(162)  评论(0编辑  收藏  举报