牛客小白月賽16 D小陽買水果(思維題)

題意簡單,求和大於0的最長連續子序列的長度。
分析:先求前綴和,把前綴和從小到大排序,如果前綴和相等把編號大的放前面,然後從前往後遍歷,記錄遍歷過程最小的編號,如果當前的編號大於最小的編號,則更新答案。注意特判n=1的情況。

於是交了如下的代碼,案例通過了90%。。。。
參考了別人的代碼,貌似加上一句n++(已註釋),就通過了,不解。。。

#include<iostream>
#include<algorithm>
#define maxn 3000000
using namespace std;
typedef long long ll;
typedef struct Node{
    int value;
    int index;
}node;
node a[maxn];
ll n;
bool cmp(node a,node b){
    if(a.value==b.value){return a.index>b.index;}
    return a.value<b.value;
}
int main()
{
    std::ios::sync_with_stdio(false);
    cin>>n;
    a[0].value=0;
    for(ll i=1;i<=n;i++){
        int x;
        cin>>x;
        a[i].value=a[i-1].value+x;
        a[i].index=i;
    }
   // n++;
    sort(a+1,a+n+1,cmp);
    int minIndex=n+1,ans=0;
    for(int i=1;i<=n;i++){
        minIndex=min(minIndex,a[i].index);
        if(a[i].index>minIndex){ans=max(ans,a[i].index-minIndex);}
    }
    cout<<ans<<endl;
    return 0;
}

一開始直接枚舉左右端點判斷最長,TLE了。

#include<iostream>
#define maxn 3000000
using namespace std;
typedef long long ll;
ll n,a[maxn],sum[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    cin>>n;
    for(ll i=1;i<=n;i++){
        cin>>a[i];
        sum[i]=sum[i-1]+a[i];
    }
    int maxx=0;
    //枚舉起點
    int ans1,ans2;
    for(int i=0;i<=n;i++){
        for(int j=n;j>=i;j--){
            if(sum[j]-sum[i]>0&&j-i>maxx){maxx=j-i;break;}
        }
        if(n-i<maxx){break;}
    }
    cout<<maxx<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章