牛客:栈的使用

题目地址:登录—专业IT笔试面试备考平台_牛客网

题目大致意思:给你一个长度为N(N<=2e6)的序列,并且所有的元素都是大于M(1<=M<=1e7),然后让你修改其中的一些值,使得每个长度为K(1<=K<=N)的区间和小于0,并且每个元素修改的最低值为-M,修改的权值为两个的差,求最小的总修改值。

样例:
输入:
4 5 2
7 5 8 10
输出:
32

解题方法:首先看下时间,就给了1s,而且数据的大小是2e6,那么做法基本上就是O(n)了。如果我们从前往后遍历,那么对于每个大于等于0的大小为K的区间的话我们修改的位置肯定是越往后面越好。随着区间的移动,最后一个位置的值都会在改变,很容易就想到了后进先出的关系于是就使用栈来做,而且对于每一个我们修改到-M的值的时候,都需要移出这个栈,因为这个值不能再小了。复杂度就是2*n。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N = 2e6+7;
int n, m, k;
LL sum, res;
int A[N], st[N], top;
inline int read() {
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while('0' <= ch && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void put(LL x) {
    if (x < 0) x = ~x + 1, putchar('-');
    if (x > 9) put(x / 10);
    putchar(x % 10 + '0');
}
int main() {
    n = read();
    m = read();
    k = read();
    for (int i = 1; i <= n; i++) {
        A[i] = read();
    }
    for (int i = 1; i < k; i++) {
        st[++top] = i;
        sum += A[i];
    }
    int pos = k;
    while (pos <= n) {
        sum -= A[pos-k];
        sum += A[pos];
        st[++top] = pos;
        while (sum >= 0) {
            int now = st[top];
            int tmp = A[now]+m;
            if (tmp > sum+1) {
                A[now] -= sum+1;
                res += sum+1;
                sum = -1;
            } else {
                A[now] -= tmp;
                res += tmp;
                top--;
                sum -= tmp;
            }
        }
        pos++;
    }
    put(res);
    return 0;
}

代码注意地方:一个long long int类型的数组必须使用%lld读入,一个int类型的数组使用%d读入,而不能为了方便,LL类型的数组用%d读入,在这一题中我就是LL类型数组使用%d读入的,因此出现了三次的段错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值