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; }