您当前的位置: 首页 >  c++

星拱北辰

暂无认证

  • 2浏览

    0关注

    1205博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

数列求和(洛谷P5745题题解,C++语言描述)

星拱北辰 发布时间:2021-04-04 02:22:12 ,浏览量:2

题目要求

题目链接

在这里插入图片描述

分析

思路参考自大佬的博客,此佬介绍了诸多解法,我学习了其中的 O ( N ) O(N) O(N)解法:

维护一个队列,让数组中的数依次入队,并记录其的元素和,若大于m,则让对首出列,更新答案,再让后面的数字继续入队,并更新答案,不断的这么操作,直到所有数字都入过队了为止。

妙哉!

按照大佬的思路写出了代码,对比了一下,可惜大佬给出的代码是有问题的,问题有二:

  1. 没初始化 (可能是故意的嘿嘿)
  2. 没有对尾部进行特判,导致漏解

我把完整AC的代码贴在下面了,自行食用,注释还是比较详细的,宁要是不想看我也没办法QAQ

AC代码
#include 
#include 

using namespace std;

int nums[4000001];

// O(N)
int main() {
    // 不初始化的都是SandBox
    int n, m, left_result = 0, right_result = 0, sum_result = 0, left = 1, sum = 0;
    cin >> n >> m;
    // 题意下标从1开始
    for (int i = 1; i > nums[i];
    }
    // 双端队列当队列用
    deque queue;
    // right指针和left指针就是要维护的区间
    for (int right = 1; right  m) {
            // 出队
            queue.pop_front();
            // 溢出了表示可以更新答案,但更新前需要去掉这个溢出值
            sum -= nums[right];
            // 更新答案
            if (sum > sum_result) {
                sum_result = sum;
                // 减去1是因为当前不能要,应该取上一个
                right_result = right - 1;
                left_result = left;
            }
            // 重新加上,不然就错过了
            sum += nums[right];
            // 删去左端点
            sum -= nums[left];
            // 出队后左端点右移一位
            left++;
        }
    }
    // 不加末尾特判的话,会忽略最后一次,会WA
    // 测试样例:
    // 10 50
    // 2 2 1 9 7 8 8 3 9 5
    // 输出:
    // 3 10 50
    if (sum > sum_result) {
        sum_result = sum;
        right_result = n;
        left_result = left;
    }
    cout             
关注
打赏
1660750074
查看更多评论
0.0523s