題意簡單,求和大於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;
}