洛谷 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;
}
posted @ 2022-09-22 21:43  Vijurria  阅读(53)  评论(0编辑  收藏  举报