题干:
链接:https://ac.nowcoder.com/acm/contest/883/B
来源:牛客网
ZYB loves binary strings (strings that only contains `0' and `1'). And he loves equal binary strings\textit{equal binary strings}equal binary strings more, where the number of `0' and the number of `1' in the string are equal.
ZYB wants to choose a substring from an original string T\ T T so that it is an equal binary string\textit{equal binary string}equal binary string with the longest length possible. He also wants to choose a subsequence of T\ T T which meets the same requirements.
A string v\ v v is a substring of a string w\ w w if v\ v v is empty, or there are two integers l\ l l and r (1≤l≤r≤∣w∣)r \ (1 \le l \le r \le |w|)r (1≤l≤r≤∣w∣) such that v=wlwl+1⋯wrv=w_lw_{l+1}\cdots w_rv=wlwl+1⋯wr. A string v\ v v is a subsequence of a string w\ w w if it can be derived from w\ w w by deleting any number (including zero) of characters without changing the order of the remaining characters.
For simplicity, you only need to output the maximum possible length. Note that the empty string is both a substring and a subsequence of any string.
输入描述:
The first line of the input contains a single integer N (1≤N≤100000)N \ (1 \le N \leq 100000)N (1≤N≤100000), the length of the original string T\ T T. The second line contains a binary string with exactly N\ N N characters, the original string T\ T T.
输出描述:
Print two integers A\ A A and B\ B B, denoting the answer for substring and subsequence respectively.
示例1
输入
复制
8 01001001
输出
复制
4 6
题目大意:
给你一个01字符串,让你求01个数相等的子串和子序列长度。
解题报告:
对于子序列肯定好说,直接就是0和1取个最大值再乘以2就是答案。
对于子串,正常想法是对于偶数长度进行二分,但是其实是没有单调性的,比如这个样例:00111100,长度为6是不成立的,长度为8是成立的。所以正解是用前缀和,记录第一个出现的位置即可。注意初始化0的初始位置是0。因为他可以从头开始取。注意取长度的时候不需要再+1了。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
const int ZERO = 1e5;
int sum[MAX];
int pos[MAX];
int num[2],n;
char s[MAX];
int main()
{memset(pos,-1,sizeof pos);cin>>n;scanf("%s",s+1);for(int i = 1; i<=n; i++) s[i] -= '0',num[s[i]]++,sum[i] = sum[i-1] + (s[i] == 0 ? -1 : 1);int ans2 = min(num[0],num[1])*2;int ans1 = 0;pos[ZERO] = 0;for(int i = 1; i<=n; i++) {if(pos[ZERO+sum[i]] != -1) ans1 = max(ans1,i - pos[ZERO + sum[i]]);else pos[ZERO+sum[i]] = i;}printf("%d %d\n",ans1,ans2);return 0 ;
}