题目:
见https://pintia.cn/problem-sets/994805342720868352/problems/994805514284679168
思路:
先求出最大连续子段和,记录一下每次更新res的i,然后再从更新点i开始从后往前推算出start
直接上代码讲解吧
AC代码:
#include<iostream>
#include<algorithm>
#include<climits>
using namespace std;
const int N=1e4+10;
int n,res=-1,a[N];
int main()
{
cin>>n;
int sum=0,_end,_start,flag=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>=0)
flag=1;
sum=max(sum,0)+a[i];//求最大连续子段和的方法
if(sum>res)
{
_end=i;
res=sum;
}
}
if(!flag)
cout<<0<<" "<<a[1]<<" "<<a[n]<<endl;
else
{
int temp=0;
for(int i=_end;i>=1;i--)
{
temp+=a[i];
if(temp==res)
{
_start=i;
break;
}
}
cout<<res<<" "<<a[_start]<<" "<<a[_end]<<endl;
}
return 0;
}
第一:先初始化最大连续子段和res=-1,如果初始化为0,可能会出现最大子段和为0的情况,这样的话我们的更新方式是if(sum>res),如果是0就没法更新了!!!
第二:更新方式之所以是sum>res,是因为题目说如果出现相等的子段和情况选取更靠前的子段和作为结果,如果我才用大于等于作为更新方式那么每次更新的结果都会更加靠后,这样不满足题目要求!!!
第三:如果所有数都是负数那么则输出0,和整个序列的头尾两个数,这里我采用了一个flag变量,如果序列中有一个大于等于0的数那么都将其赋值为1