[PAT练习官网]
题目
解析
题目的大意就是给定一个序列,找出和最大的子序列,输出最大子序列的和,还有该子序列的起始元素和最后元素。
做这个题目是根据浙大在mooc的数据结构课程,求最大子序列的启发,采用__在线处理__可以降低时间复杂度至O(n)
代码
#include <stdio.h>
int main()
{
int k, a[10001];
scanf("%d", &k);
int start = 0, end1 = k-1, sum=0, maxsum=0, temp1=0, temp2=0;//temp1和temp2暂存起始和结束位置
for(int i=0; i<k; i++){
scanf("%d", &a[i]);
}
for(int i=0; i<k; i++){
if(sum >= 0){
sum += a[i];
temp2 = i; //累加则结束位置更新
}
else {
sum = a[i]; //sum小于0时前面的序列就没用了
temp1 = temp2 = i; //更新初始和结束位置
}
if(sum > maxsum || sum == 0 && end1 == k-1){
maxsum = sum;
start = temp1;
end1 = temp2;
}
}
printf("%d %d %d", maxsum, a[start], a[end1]);
}
注意事项,就是需要先暂时记录下来子序列的起始和终止位置,而不是更新最终的start和end,这是因为在一些情况下可能有多个相同的和相同的子序列,直接更新的话会发生错误
我踩过的一些坑
最初几次提交都是部分正确,后来找到原因是一些数据的初值设定有问题,初始的start和end必须是0和k-1,这是因为在特殊情况下(如整个数列全为正),就会导致一些问题。
还有一些小细节就是在赋值k-1时,一定要在scanf("%d", &k);后面