码迷,mamicode.com
首页 > 其他好文 > 详细

Educational Codeforces Round 30 B.Balanced Substring

时间:2020-06-14 16:38:35      阅读:51      评论:0      收藏:0      [点我收藏+]

标签:lan   长度   put   字符   type   can   cal   之间   ble   

题目:

You are given a string s consisting only of characters 0 and 1. A substring [l,?r] of s is a string sl,sl?+?1,sl?+?2... sr, and its length equals to r?-?l?+?1. A substring is called balanced if the number of zeroes (0) equals to the number of ones in this substring.

You have to determine the length of the longest balanced substring of s.

Input
The first line contains n (1?≤?n?≤?100000) — the number of characters in s.

The second line contains a string s consisting of exactly n characters. Only characters 0 and 1 can appear in s.

Output
If there is no non-empty balanced substring in s, print 0. Otherwise, print the length of the longest balanced substring.

Examples
input
8
11010111
output
4

input
3
111
output
0

Note
In the first example you can choose the substring [3,?6]. It is balanced, and its length is 4. Choosing the substring [2,?5] is also possible.

In the second example it‘s impossible to find a non-empty balanced substring.

解析:题意是让你找出在该段01串中,1与0数量相等的连续子串,输出该子串长度。思路:前缀和。
这道题首先比较巧妙,先把"0"变成"-1"这样在求前缀和的时候假如0和1的数量相等,那么它们的前缀和便为0。此外,我们还需开一个数组,目的是记录是否到某一段前缀和与之前求过的前缀和相等,直接说这句话有点傻逼,举个例子来说,比如该字符串为101011,这里最长平衡01串是1010/0101,我这里主要解释一下0101,当遍历第一个1的时候计算前缀和为1,那这时候可以开一个数组num[前缀和] = 当前字符位置,也就是num[1] = 1,接着到第三个1的是时候前缀和 = 1 +(-1) + 1 +(-1)+ 1 = 1,这时候就去看看num[1]是否已经有值在里面,假如说有值在里面,说明之前已经有求过相等的前缀和,那它们直接的01串肯定是平衡的,这个很好理解吧,也就是0101是平衡,那它的长度也就是 5 - 1 = 4。这里有点小坑,也就是它们的前缀和可能是负数,所以第一个前缀和就不是1,而是一个比较大的数+1,我这里取1e5+7,实际上就是换了一个原点罢了,假如想减少空间的浪费可以用STL的map。

AC代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
char str[maxn];
int num[maxm], a[maxn], n;

int main()
{
	scanf("%d", &n);
	scanf("%s", str + 1);
	for(int i = 1; i <= n; i++)
	{
		if(str[i] == ‘1‘)
			a[i] = 1;
		else
			a[i] = -1;
		a[i] += a[i-1];
	}
	memset(num, 0, sizeof(num));
	int ans = 0;
	for(int i = 1; i <= n; i++)
	{
		int sum = a[i] + maxn; //避免前缀和是负数 
		if(sum == maxn)
			ans = max(ans, i); //前缀和为0,说明从第一个字符到最后一个字符满足01平衡
		if(num[sum]) //当下一次遇到前缀和仍为sum时,说明与上一次为sum之间的序列01平衡 
			 ans = max(ans,i - num[sum]);
		else
			num[sum] = i; //记录第一次求和为sum时的下标 
	}
	printf("%d", ans);
	return 0;
} 

Educational Codeforces Round 30 B.Balanced Substring

标签:lan   长度   put   字符   type   can   cal   之间   ble   

原文地址:https://www.cnblogs.com/K2MnO4/p/13125129.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!