D 小阳买水果

链接:https://ac.nowcoder.com/acm/contest/949/D
来源:牛客网

题目描述

水果店里有 nn个水果排成一列。店长要求顾客只能买一段连续的水果。
小阳对每个水果都有一个喜爱程度 aiai,最终的满意度为他买到的水果的喜欢程度之和。
如果和为正(不管是正多少,只要大于 00 即可),他就满意了。
小阳想知道在他满意的条件下最多能买多少个水果。
你能帮帮他吗?

输入描述:

第一行输入一个正整数 n,表示水果总数。

第二行输入 n 个整数 aiai,表示小阳对每个水果的喜爱程度。

输出描述:

一行一个整数表示结果。(如果 1 个水果都买不了,请输出 0)
示例1

输入

5
0 0 -7 -6 1

输出

1

思路:用一个结构体保存每个的前缀和和位置。按照前缀和由大到小排序,前缀和相等的按位置由大到小排。在遍历一遍。记录已经遍历过
的最小位置minx,如果现在遍历的点的位置a[i].pos大于前面最小位置,就可以更新答案了(a[i].pos-minx),因为前缀和比它大,一定是
正数。

但是要注意的是一定要加个零点,前缀和为0,位置为0,如果测试样例只有一个点 1,就没有比较的点了,所以要加个零点。
其实前缀和相等按位置由大到小排是很重要的,因为保证了前面的最小位置前缀和一定小于它。不会出现前缀和相等的情况,而导致更新的
答案错误。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=2e6+100;
struct node{
    int num,pos;
}e[maxn];
bool cmp(node a,node b)//排序 
{
    if(a.num==b.num)
        return a.pos>b.pos;
    return a.num<b.num;
}
int main()
{
    int n,x;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        e[i].num=x+e[i-1].num;//前缀和 
        e[i].pos=i;//位置 
    }
    n++;
    sort(e+1,e+n+1,cmp);
    int minx=n;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        minx=min(minx,e[i].pos);
        if(e[i].pos>minx)
            ans=max(ans,e[i].pos-minx); 
    }
    printf("%d\n",ans);
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/xiongtao/p/11183197.html
d
<d>
今日推荐