【算法和数据结构】仓库日志

题目描述

​ 某仓库购入新的货物(每次购入的货物均不同)并将一部分老货物发出,这个过程会有软件对数据以日志形式保存,规则如下:

​ 该日志记录了两类操作:第一类操作为入库操作,以及该次入库的货物数量;第二类操作为出库操作。这些记录都严格按时间顺序排列。入库和出库的规则为先进后出,即每次出库操作货物为当前在仓库里所有货物中最晚入库的货物。

​ 为了便于分析,现在加入了第三类查询操作,每次查询时,输出当前仓库数量最多的货物的数量。

输入

 输出

样例输入

13
0 1
0 2
2
0 4
0 2
2
1
2
1
1
2
1
2

样例输出

2
4
4
1
0

 

关键词:

分析:

这道题重点在于需要用高效的方法获取最大的元素。

仓库中的元素不断的出栈和入栈,可能改变栈当中最大元素的情况只有两种:

1. 新加入的元素大于等于目前栈当中的最大的元素。

2. 出栈的元素是当前栈中的最大元素。

便发现,改变栈中最大元素的时刻只会在进出时发生,如果进入栈中的新元素比栈最大元素小,则入栈和出栈不会对栈中最大元素大小造成影响。

如此,就利用一个栈专门来保存栈中最大元素。

代码:

#include <iostream>
#include <vector>

#include <stack>


using namespace std;

class Cargo {
public:
    Cargo() {
    }

    void store(int n) {
        stuffs.push_back(n);
        if (maxVals.empty() || n >= maxVals.top()) {
            maxVals.push(n); // when there is a new highest number, push that number into stack
        }
        // cout << "now high is " << high << endl;
    }

    void out() {
        if (isEmpty())
            return;
        int popNumber = stuffs.back();
        stuffs.pop_back();
        if (popNumber == maxVals.top()) {
            maxVals.pop();
        }        
    }

    bool isEmpty() {
        if (stuffs.empty()) {
            return true;
        }
        return false;
    }

    void mostLotCargo() {
        if (isEmpty()) 
            opResult.push_back(0);
        // return this->high;
        else {
            opResult.push_back(maxVals.top());
        }
    }


    void showOpResult() {
        for (auto &ele : opResult) {
            printf("%d\n", ele);
        }
    }

    void showStuffs() {
        // cout << "show stuffs " << endl;
        for (auto ele : stuffs) {
            cout << ele << " ";
        }
        cout << endl;
    }

private:
    vector<int> stuffs;
    stack<int> maxVals;
    vector<int> opResult;

};

// main

int main() {
    Cargo c;

    int numberOfOps;
    cin >> numberOfOps;

    for (int i = 0; i < numberOfOps; i++) {
        int op;
        scanf("%d", &op);
        if (op == 0) {
            int number;
            scanf("%d", &number);
            c.store(number);
        }

        else if (op == 1) {
            c.out();
        }
        else if (op == 2) {
            c.mostLotCargo();
        }
        // c.operation(op);
    }

    c.showOpResult();
    // c.showStuffs();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值