PTA1007

题目大意:给出一个包含k个整数的数组,求该数组的最大连续子序列。

解法思路:最简单的方法是暴力搜索,读入数据的同时构造前缀和数组,然后一个二层的循环做减法计算sum[i,j]表示下标i和j之间的整数和。但考虑到k最大为10000,二层循环在数据量较大的情况下会比较慢,时间也可能会不够(时限200ms)。

所以考虑到,读入数据后,当我们遍历到a[i]时,那么以a[i]为结尾的最大连续子序列,要么是在a[i-1]后面再续一个a[i],要么自己作为开头,所以这样只需一遍遍历,就可完成最大连续子序列和的求解。这样时间复杂度仅为O(n)。

注:题目还有一个要求,If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.翻译过来是:“如果所有K个数都是负数,那么它的最大和被定义为0,你应该输出整个序列的第一个和最后一个数。”但实际数据应该是,当最后求出的最大和小于0时,才把最大和定义为0输出,并输出整个序列的第一个和最后一个数。因为我开始是按照题目要求在代码中加了个bool判断是否所有k个数都是负数,如果是负数则按要求输出,但发现最后还是有一个数据点出错。改成我自己认为合理的要求后,才AC掉。题目描述错了。

代码:

#include <iostream>
#include <limits.h>
using namespace std;

struct As
{
    int maxsum; //表示包含当前位置的最大数列和
    int head; //表示最大数列和的开头位置
};

int main()
{
    int k;
    cin>>k;
    As a[10000];
    int subs[10000];
    bool B=true;
    for(int i=0;i<k;i++)
    {
        cin>>subs[i];
        if(subs[i]>0) B=false;
    }
    a[0].head=0;
    a[0].maxsum=subs[0];
    for(int i=1;i<k;i++)
    {
        if(a[i-1].maxsum+subs[i]>=subs[i])
        {
            a[i].maxsum=a[i-1].maxsum+subs[i];
            a[i].head=a[i-1].head;
        }
        else
        {
            a[i].maxsum=subs[i];
            a[i].head=i;
        }
    }
    int headd,taill;
    int answer=-INT_MAX;
    for(int i=0;i<k;i++)
    {
        if(a[i].maxsum>answer)
        {
            headd=a[i].head;
            taill=i;
            answer=a[i].maxsum;
        }
    }
    if(answer<0)
    {
        answer=0;
        headd=0; taill=k-1;
    }
    cout <<answer<<" "<<subs[headd]<<" "<<subs[taill]<< endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值