给定一个01串S,求出它的一个尽可能长的子串S[
i..j],满足存在一个位置i<=x <=j, S[i..x]中0比1多,而S[x + 1..j]中1比0多。求满足条件的最长子串长度。
Input
一行包含一个只由0和1构成的字符串S。 S的长度不超过1000000。
Output
一行包含一个整数,表示满足要求的最长子串的长度。
Input示例
10
Output示例
0
思路:首先将0代表的值进行更换为-1,那么这道题就转变成求一个最大的区间,使得前半个区间的和小于0,以及后半个区间的和大于0,然后对每一个位置进行查找她为中间的区分点的话,前半部分以及后半部分所能达到的最大值,最后将两个值进行相加去最大的值就是本题的解。
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
char str[1000200];
int left1[1000200];
int right1[1000200];
int v[1001000];
int main(){
while(scanf("%s",str+1)!=EOF){
int len = strlen(str+1);
memset(v,0,sizeof(v));
int px = 0;
for(int i=1;i<=len;i++){
if(str[i] == '0'){
px--;
}else{
px++;
}
if(px<0){
left1[i] = i;
}else{
if(v[px+1] != 0){
left1[i] = i - v[px+1];
}else{
v[px] = i;
left1[i] = 0;
}
}
}
px = 0;
memset(v,0,sizeof(v));
for(int i=len;i>0;i--){
if(str[i] == '1'){
px--;
}else{
px++;
}
if(px<0){
right1[i] = len-i+1;
}else{
if(v[px+1]!=0){
right1[i] = v[px+1] - i;
}else{
v[px] = i;
right1[i] = 0;
}
}
}
int maxx = 0;
for(int i=1;i<len;i++){
if(left1[i]>0 && right1[i+1]>0 && maxx<(left1[i]+right1[i+1])){
maxx = left1[i] + right1[i+1];
}
}
printf("%d\n",maxx);
}
return 0;
}