最长配对
将所有0在开始时与处理为-1,这样只要求前缀和为0的最大区间长度即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 50005;
int sum[maxn];
int main(){
int n;
memset(sum,0,sizeof(sum));
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
if(x==0){
sum[i]=sum[i-1]-1;
}
else{
sum[i]=sum[i-1]+1;
}
}
int ans=-1;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(sum[j]-sum[i-1]==0)
ans=max(ans,j-i+1);
}
}
cout<<ans<<endl;
return 0;
}
第二种方法是用一个二维数组存一下前i个数中0和1的个数时候相等即可,但是要从最大的区间长度开始遍历,当有一组满足条件是跳出即可,这个肯定是最大的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 50005;
int a[maxn][2];
//int a[maxn];
int n,ans;
int main(){
scanf("%d",&n);
a[0][0]=0;
a[0][1]=0;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
if(x==0){
a[i][0]=a[i-1][0]+1;
a[i][1]=a[i-1][1];
}
else{
a[i][0]=a[i-1][0];
a[i][1]=a[i-1][1]+1;
}
}
for(int i=n;i>=1;i--){
int num0,num1;
//cout<<"长度为"<<i<<endl;
for(int j=1;j<=n-i+1;j++){
// cout<<j<<" "<<j+i-1<<endl;
num0=a[j+i-1][0]-a[j-1][0];
num1=a[j+i-1][1]-a[j-1][1];
if(num0==num1&&num0==i/2){
ans=i;
break;
}
}
if(num0==num1&&num0==i/2){
cout<<ans<<endl;
break;
}
}
return 0;
}