这题和求最大子列和一样,就是多了找出该最大子列和的首尾元素,若最大子列和Maxsum<0,就输出该数组的首尾元素a[0] 和 a[ n-1 ].
第一个方法是二重循环
#include<bits/stdc++.h>
using namespace std;
int a[100100];
int main()
{
int n,k;
cin>>n;
int i=0,j,min=0;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]<0)
min+=a[i];
}
int Thissum=0,Maxsum=min;
int minl,minr;
for(i=0;i<n;i++)
{
Thissum=0;
for(j=i;j<n;j++)
{
Thissum+=a[j];
if(Thissum>Maxsum)
{
Maxsum=Thissum;
minl=i;//记录最大子列和的首元素下标;
minr=j;//记录最大子列和的尾元素下标;
}
}
}
if(Maxsum<0)
{
cout<<"0 "<<a[0]<<" "<<a[n-1]<<endl;
}
else
cout<<Maxsum<<" "<<a[minl]<<" "<<a[minr]<<endl;
return 0;
}
测试点 提示 结果 耗时 内存
0 sample换1个数字。有正负,负数开头结尾,有并列最大和 答案正确 3 ms 512KB
1 最大和序列中有负数 答案正确 2 ms 512KB
2 并列和对应相同i但是不同j,即尾是0 答案正确 2 ms 384KB
3 1个正数 答案正确 2 ms 384KB
4 全是负数 答案正确 2 ms 384KB
5 负数和0 答案正确 2 ms 384KB
6 最大和前面有一段是0 答案正确 2 ms 384KB
7 最大N 答案正确 38 ms 384KB
第二方法就是在线处理 更快
#include<bits/stdc++.h>
using namespace std;
int a[100100];
int main()
{
int n,k;
cin>>n;
int i=0,j,min=0;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]<0)
min+=a[i];
}
int Thissum=0,Maxsum=min;
int l=0, minl,minr;
minl=minr=0;
for(i=0;i<n;i++)
{
Thissum+=a[i];
if(Thissum<0)
{
Thissum=0;
l=i+1;
}
else if(Thissum>Maxsum)
{
Maxsum=Thissum;
minr=i;
minl=l;
}
}
if(Maxsum<0)
{
int x=a[0];
int y=a[n-1];
cout<<"0 "<<x<<" "<<y<<endl;
}
else
cout<<Maxsum<<" "<<a[minl]<<" "<<a[minr]<<endl;
return 0;
}
测试点 提示 结果 耗时 内存
0 sample换1个数字。有正负,负数开头结尾,有并列最大和 答案正确 3 ms 384KB
1 最大和序列中有负数 答案正确 4 ms 512KB
2 并列和对应相同i但是不同j,即尾是0 答案正确 3 ms 500KB
3 1个正数 答案正确 3 ms 416KB
4 全是负数 答案正确 3 ms 424KB
5 负数和0 答案正确 3 ms 512KB
6 最大和前面有一段是0 答案正确 3 ms 368KB
7 最大N 答案正确 3 ms 512KB