Coexit

题目描述

位于欧洲中部的赫希费尔登狩猎保护区生活着许多动物,雄壮的野牛和凶狠的狼群之间保持着一种平
衡,当野牛的数量和狼群一样多时,它们彼此互不侵犯相安无事,但只要狼的数量多于野牛狼群就会攻
击牛群,而野牛数量占多数时,它们会驱逐狼群到别的地方。
当地的统计学家把牛群和狼群分布通过0和1表示为一个字符串S,S的字串可以表示一个区域内的牛和狼
总数,请你根据这个统计字符串,判断出来这个保护区内能共存最多头野牛和狼的区域,该区域的牛群
和狼群总数是多少。

输入格式

一个字符串,只包含01,长度不超过1000000。

输出格式

一行一个整数,最长的0与1的个数相等的子串的长度。

数据范围

对于10%的数据,字符串长度≤10;
对于100%的数据,字符串长度≤1000000。

样例1

输入

1011

输出

2

样例2

输入

0010100

输出

4

样例3

输入

111

输出

0

题解

本题非常的巧妙,算是以后编程的又一个思路。要找字符串里0,1个数相等的子串,那我们可以把0变成-1,如果相加=0了,那么个数就相等了。本题非常的巧妙,算是以后编程的又一个思路。要找字符串里0,1个数相等的子串,那我们可以把0变成-1,如果相加=0了,那么个数就相等了。

1.先用前缀和求出前i个数字的和,这样要求任意一个子串的总和就简单了。

2.求完之后,用f[sum[i]]表示前面字符串总和为sum[i]的数字的位置,注意,这里存的是位置,而且一定是最靠前的位置(因为只有第一遍扫到的时候存了),sum[i]是下标,类似于桶排的思想。

3.如果循环到一个f已经被标记过了,那么就算出,他们之间的距离,取max。

4.细节非常重要。
(1)因为可能前面的和是负数,但是下标不能是负数,所以可以给小于0的sum[i]加上一个大数,使它为正。
(2)因为前面的总和也可能是0,所以f要赋-1。
(3)取max时,maxx的初值应该赋成0,因为,如果没有找到就要输出0,当然,这里也可以用一个bool来实现
(4)在刚开始计算前缀和的时候,应该用sum[i+1]=sum[i]-1,这样处理后面的操作比较方便。

代码如下:

#include<bits/stdc++.h>
using namespace std;
string s;
int sum[1000050],f[50000000];
int main()
{
	freopen("coexist.in","r",stdin);
	freopen("coexist.out","w",stdout);
	cin>>s;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]=='0') sum[i+1]=sum[i]-1;
		else sum[i+1]=sum[i]+1;
	}
	memset(f,-1,sizeof(f));
	int maxx=0;
	f[0]=0;
	for(int i=1;i<=s.size();i++)
	{
		if(sum[i]<0) sum[i]+=2000000;
		if(f[sum[i]]==-1) f[sum[i]]=i;
		else maxx=max(maxx,i-f[sum[i]]);
	}
	cout<<maxx;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值