洛谷P1114 “非常男女”计划

该文描述了一种算法问题,通过维护数组d[i]存储位置i及其之前男生数减女生数的差,寻找男生数等于女生数的区间。使用两个额外数组记录相同d[i]值的最左侧和最右侧,遍历所有可能的d[i]值以找到最大合法区间长度。
摘要由CSDN通过智能技术生成

题面:

真是引人浮想联翩的题目呢~在千万题海中一眼选中!

解题:

引入数组d[ i ]储存第i个位置及它本身之前,男生数-女生数的和;

这样,d[ i ]相等的两个数围成的区间,男生数=女生数,即我们所求的合法区间,

定义两个数组,l[ ]和r[ ],储存每个d[ i ]可能值的最左、最右出现的位置,

枚举所有d[ i ]可能值,过程中不断更新ans的最大值

注意:首端也需要默认为一个0的位置,即:d[0]=0,

否则对于2 1 0这样需要连接至首端的数据,给出的答案为0!

AC代码奉上

#include<iostream>
#include<algorithm>
#define MAXN int(1e6+5)

using namespace std;

int n, p, ans = 0, minNum = MAXN, maxNum = -1, d[MAXN] = { 0 }, l[MAXN] = { 0 }, r[MAXN] = { 0 };

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> p;

        if (p == 1)d[i] = d[i - 1] + 1;
        else d[i] = d[i - 1] - 1;

        minNum = min(minNum, d[i]);
        maxNum = max(maxNum, d[i]);
    }

    for (int i = 1; i <= n; i++)
    {
        if (l[d[i]] == 0 && d[i] != 0) { l[d[i]] = i; }  //没有左极限,初始化左极限
        else { r[d[i]] = i; }               //若发现更大的右极限,不断右移右区间
    }

    if (r[0] != 0)ans = max(ans, r[0]);  //首个数字前有个隐藏的d[0]=0
    for (int i = minNum; i <= maxNum; i++)
        if (l[i] != 0 && r[i] != 0)
            ans = max(ans, r[i] - l[i]);

    cout << ans << endl;

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值