题目链接:B-Crazy Binary String
题意:给你一个只有0和1的字符串,找0和1相同数量的最大子串和子序列(子串是连续的,子序列是可以不连续的)
题解:子序列很简单,0和1数量少的那个乘以2就行了
子串可以用前缀和来做,字符是1记为1,0记为-1,做完前缀和后,s[r] - s[l-1]=0 就是满足题目要求的子串。
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 100005;
const int temp = 100000;
string s;
int a[maxn];
int sum[maxn];
int sum0 = 0, sum1 = 0;
int maxlian = 0;
vector<vector<int> >cnt(2 * maxn);
int n;
int main()
{
cnt[0 + temp].push_back(0);
cin >> n;
cin >> s;
for (int i = 0; i < n; i++) {
a[i + 1] = s[i] - '0';
if (a[i + 1] == 0)
sum0++;
if (a[i + 1] == 1)
sum1++;
}
for (int i = 1; i <= n; i++) {
if (a[i] == 0)
sum[i] = sum[i - 1] - 1;
else
sum[i] = sum[i - 1] + 1;
cnt[sum[i] + temp].push_back(i);
}
if (!cnt[0+temp].empty())
maxlian = cnt[0+temp].back();
for (int i = 1; i <= n; i++) {
maxlian = max(maxlian, cnt[sum[i] + temp].back() - i);
}
int maxbulian = min(sum0, sum1);
cout << maxlian << " " << maxbulian * 2 << endl;
}
标程
#include<bits/stdc++.h>
#define N 100005
using namespace std;
map<int,int>G;
int a[N],n;char s[N];
int main(){
//freopen("test7.in","r",stdin);
scanf("%d",&n);
scanf("%s",s+1);
for (int i=1;i<=n;i++)
a[i]=a[i-1]+((s[i]=='1')?1:-1);
//a[r]-a[l-1]==0
int ans=0;
G[0]=0;
for (int i=1;i<=n;i++)
//map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。
if (G.find(a[i])!=G.end())
ans=max(ans,i-G[a[i]]);
else
G[a[i]]=i;
int zero=0,one=0;
for (int i=1;i<=n;i++)
if (s[i]=='0') zero++;else one++;
printf("%d %d\n",ans,min(zero,one)*2);
}