51nod 1391 01串(模拟)

来源:互联网 发布:mac日历广告如何禁止 编辑:程序博客网 时间:2024/06/10 13:50
1391 01串
题目来源: Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
 收藏
 关注
给定一个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;}


0 0