洛谷 P1114 “非常男女”计划 (前缀和)
https://www.luogu.com.cn/problem/P1114
题目大意:
给定一排数字,让我们求出最大的区间内1和0的个数相等时的区间长度。
输入
9
0 1 0 0 0 1 1 0 0
输出
6
输入
10
0 1 1 1 1 1 0 0 0 0
输出
10
虽然这题给我磨出来了,但是还是想写一篇题解记录一下思维
-
遇到0时候可以采取➕1,遇到1的时候➖1
-
(0➖1,1➕ 1也行,看自己的习惯,答案都是一样的)
-
然后我们可以发现,任意两个相同的s[i]数字的位置内部,1和0的个数一定是均衡的
-
所以就直接转换到比较相同的数字的左右之差就行了
温馨提醒0的位置
- 一开始没有任何数字的时候0就已经存在了,所以0的左边其实就已经固定好了在0这个位置
不理解的话可以手动模拟一下样例二(一开始卡我的地方也就是这里)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL N=500200,M=2002;
#define l first
#define r second
LL a[N],s[N];
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
LL T=1;
//cin>>T;
while(T--)
{
LL n;
cin>>n;
map<LL,PII> mp;
LL maxn=0,minn=0;
for(LL i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]==1) s[i]=s[i-1]+1;//遇到1直接加1
else s[i]=s[i-1]-1;//遇到0直接退一步
minn=min(minn,s[i]);
maxn=max(maxn,s[i]);
if(s[i]!=0&&mp[s[i]].l==0) mp[s[i]].l=i,mp[s[i]].r=i;
else mp[s[i]].r=i;
//cout<<s[i]<<" ";
}
// cout<<endl;
//cout<<minn<<" "<<maxn<<endl;
LL ans=0;
for(LL i=minn;i<=maxn;i++)
{
//cout<<mp[i].l<<" "<<mp[i].r<<endl;
ans=max(ans,mp[i].r-mp[i].l);
}
cout<<ans<<endl;
}
return 0;
}