题目描述
位于欧洲中部的赫希费尔登狩猎保护区生活着许多动物,雄壮的野牛和凶狠的狼群之间保持着一种平衡,当野牛的数量和狼群一样多时,它们彼此互不侵犯相安无事,但只要狼的数量多于野牛狼群就会攻击牛群,而野牛数量占多数时,它们会驱逐狼群到别的地方。
当地的统计学家把牛群和狼群分布通过0和1表示为一个字符串S,S的字串可以表示一个区域内的牛和狼总数,请你根据这个统计字符串,判断出来这个保护区内能共存最多头野牛和狼的区域,该区域的牛群和狼群总数是多少。
输入
一个字符串,只包含01,长度不超过1000000。
输出
一行一个整数,最长的0与1的个数相等的子串的长度。
样例输入
1011
样例输出
2
提示
对于1011而言,它表示保护区内分布情况为:[牛,狼,牛,牛],那么最多只有[狼,牛]这2只动物存在于某个区域内,所以结果为2
对于10%的数据,字符串长度≤10;
对于100%的数据,字符串长度≤1000000。
思路
求最长01相等的字串,因此从0开始递推,当s[i]=='0’时,sum[i]-=1,否则sum[i]+=1,若之前存在与sum[i]相等的点,那么该点与i点的距离就是01字串的长度。
代码实现
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000005;
const int M=10005;
const int INF=0x3f3f3f3f;
const int mod=1000000007;
typedef pair<int,int>P;
char s[N];
int dp[N];
unordered_map<int,int>mp;
int main()
{
scanf("%s",s+1);
int len=strlen(s+1);
int ans=0;
mp[0]=0;
for(int i=1;i<=len;i++)
{
dp[i]=dp[i-1];
if(s[i]=='1') dp[i]+=1;
else dp[i]-=1;
if(mp.count(dp[i])) ans=max(i-mp[dp[i]],ans);
else mp[dp[i]]=i;
}
printf("%d\n",ans);
return 0;
}