題意:操場上有一排男女的隊伍,現在需要找到一個連續的子隊伍(就是整個隊伍中截取連續的一部分或者全部), 在這個子隊伍中需要滿足: 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;
}