链接:https://ac.nowcoder.com/acm/contest/949/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
水果店里有 nn个水果排成一列。店长要求顾客只能买一段连续的水果。
小阳对每个水果都有一个喜爱程度 aiai,最终的满意度为他买到的水果的喜欢程度之和。
如果和为正(不管是正多少,只要大于 00 即可),他就满意了。
小阳想知道在他满意的条件下最多能买多少个水果。
你能帮帮他吗?
输入描述:
第一行输入一个正整数 n,表示水果总数。 第二行输入 n 个整数 aiai,表示小阳对每个水果的喜爱程度。
输出描述:
一行一个整数表示结果。(如果 1 个水果都买不了,请输出 0)
示例1
输入
复制
5 0 0 -7 -6 1
输出
复制
1
备注:
1≤n≤2×106,|ai|≤103
数据范围是2e6,所以需要一个基本线性的做法,又是一个就长度的题,所以我们把前缀和和位置记录下来,然后按前缀和从小到大排,这样的效果是排完序后,每一个后面的位置如果大于遍历过来的最小位置值,就可以参与更新,然后需要设置一个位置0且值为0的值,因为可能只有一个长度的满足,还有对于前缀和相等的要让位置大的优先,因为题目要求的是正数,为0也不可以,所以如果是小的位置优先的话,你会发现你有可能把和为0的长度参与更新
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e6+9;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
int a[maxn];
struct rt{
int sum,id;
}arr[maxn];
bool cmp(rt a,rt b){
if(a.sum==b.sum)return a.id>b.id;
return a.sum<b.sum;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
arr[0].sum=0; arr[0].id=0;
for(int i=1;i<=n;i++){
arr[i].sum=arr[i-1].sum;
arr[i].sum+=a[i];
arr[i].id=i;
}
sort(arr,arr+1+n,cmp);
int minx=0x3f3f3f3f;
int ans=0;
for(int i=0;i<=n;i++){
minx=min(minx,arr[i].id);
if(arr[i].id>minx){
ans=max(ans,arr[i].id-minx);
}
}
printf("%d\n",ans);
return 0;
}