链接:https://ac.nowcoder.com/acm/contest/949/D
来源:牛客网
题目描述
水果店里有 nn个水果排成一列。店长要求顾客只能买一段连续的水果。
小阳对每个水果都有一个喜爱程度 aiai,最终的满意度为他买到的水果的喜欢程度之和。
如果和为正(不管是正多少,只要大于 00 即可),他就满意了。
小阳对每个水果都有一个喜爱程度 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 ",ans); return 0; }