题意:操场上有一排男女的队伍,现在需要找到一个连续的子队伍(就是整个队伍中截取连续的一部分或者全部), 在这个子队伍中需要满足: s[i...x]中的男生比女生多,而s[x+1...j]中的女生比男生多(在这里, i, j表示子队伍的起点和终点,至少有一个x),求满足条件子队伍的最长长度,没有满足的子队伍时,输出0。
注:i<=x<j
思路:设a[i]表示从0到i的男生数减女生数的值。用a[i]画线,
1.线中存在凸起(a[i]>a[i-1]&&a[i]>a[i+1]),必存在s[i...x]中的男生比女生多,而s[x+1...j]中的女生比男生多,
2.若无凸起并且a[0]<0,则没有满足的子队伍时,输出0。
3.若a[0]=1,也算一个凸起
4.若凸起a[i]>0,只需从后往前找第一个小于a[i]的数的下标
5.若凸起a[i]<=0,需从前往后和从后往前各找第一个小于a[i]的数的下标
代码如下:
#include<bits/stdc++.h>
using namespace std;
char b[1000010];
int a[1000010];
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s",b);
int n=strlen(b);
for(int i=0;i<n;i++){
if(b[i]=='0')a[i]=1;
else a[i]=-1;
}
for(int i=1;i<n;i++){
a[i]+=a[i-1];
}
int t=n-1,x=0,maxx=-10000000,l,r;
if(a[x]==1)maxx=1;
for(int i=1;i<t;i++){
if(a[i]>a[i-1]&&a[i]>a[i+1]){
if(maxx<a[i]){
maxx=a[i],x=i;
}
}
}
if(x==0&&a[x]<0)printf("0\n");
else{
if(a[x]>0){
for(int i=t;i>x;i--){
if(a[x]>a[i]){
r=i;break;
}
}
printf("%d\n",r+1);
}else{
for(int i=0;i<x;i++){
if(a[x]>a[i]){
l=i;break;
}
}
for(int i=t;i>x;i--){
if(a[x]>a[i]){
r=i;break;
}
}
printf("%d\n",r-l);
}
}
}
return 0;
}