题目翻译:
求最大子段和,输出最大字段和以及起始和终止位置对应的值。
题解思路:
首先求前缀和,然后从前向后遍历找到差值最大的两个元素即可(注意前者小,后者大)。
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int K, pos_low=0, head, tail, Max=-1;
cin >> K;
int a[K+1],sum[K+1]={0};
for (int i = 1;i <= K;i++)//求得前缀和
{
cin >> a[i];
sum[i] =sum[i-1] + a[i];
}
for (int i = 1;i <= K;i++)//从前到后求得差值最大的两个元素的位置
{
if (sum[i] - sum[pos_low] > Max)
{
Max = sum[i] - sum[pos_low];
head = a[pos_low + 1];
tail = a[i];
}
if (sum[pos_low] > sum[i])
pos_low = i;
}
if (Max < 0)//全是负数
cout << 0 << " " << a[1] << " " << a[K];
else
cout << Max << " " << head << " " << tail;
}
坑点:
如果全为负,则需要输出0,起始位置值,结束位置值;因此最好把结果Max先设置为-1,如果最后Max<0则证明全是负数。
二刷:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n;
int val[N], sum[N];
int res=-1, head, tail;
int main() {
cin >> n;
for (int i = 1;i <= n;i++) cin >> val[i];
for (int i = 1;i <= n;i++) sum[i] = sum[i - 1] + val[i];
int low_pos = 0;
for (int i = 1;i <= n;i++) {
if (sum[i] - sum[low_pos] > res) {
head = low_pos;
tail = i;
res = sum[i] - sum[low_pos];
}
if (sum[i] < sum[low_pos])
low_pos = i;
}
if (*max_element(val + 1, val + n) < 0)
cout << 0 << " " << val[1] << " " << val[n];
else
cout << res << " " << val[head+1] << " " << val[tail];
}