Educational Codeforces Round 87 (Rated for Div. 2) B. Ternary String 二分

求每一种字符出现次数的前缀和,然后二分答案的长度就可


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL N=2e5+10;
string s;
int cnt[N][3]; //求前缀和,然后二分
int binarySearch(){
	int left=3;
	int right=s.length();
	int mid=0;
	int ans=0;
	while(left<=right){
		mid=(left+right)>>1;
		bool flag=false;
		rep(i,0,s.length()-mid+1){
			if(cnt[i+mid][0]-cnt[i][0]>0&&cnt[i+mid][1]-cnt[i][1]>0
				&&cnt[i+mid][2]-cnt[i][2]>0){
				flag = true;
				break;
			}
		}
		if(flag){
			ans=mid;
			right=mid-1;
		}else{
			left=mid+1;
		}
	}
	return ans;
}
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	LL _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
		s="";
		cin>>s;
		if(s.length()<3){
			cout<<0<<endl;
			continue;
		}
		cnt[0][0]=cnt[0][1]=cnt[0][2]=0;
		rep(i,0,s.length()){
			rep(j,0,3)
				cnt[i+1][j]=cnt[i][j];
			cnt[i+1][s[i]-'1']++;
		}
		cout<<binarySearch()<<endl;
	}
	return 0;
}
posted @ 2020-05-17 22:20  CrosseaLL  阅读(256)  评论(0编辑  收藏  举报