计蒜客 数据结构 栈 模板倒水问题

//单调递减栈
//题目:
//我们来看看这样一道题:地上从左到右竖立着 n 块木板,从 1 到 n 依次编号,(10,5,8,12,6)
//如下图所示。我们知道每块木板的高度,在第 n 块木板右侧竖立着一块高度无限大的木板,
//现对每块木板依次做如下的操作:对于第 i 块木板,我们从其右侧开始倒水,
//直到水的高度等于第 i 块木板的高度,倒入的水会淹没 ai 块木板(如果木板左右两侧水的高度大于等于木板高度即视为木板被淹没),
//求 n 次操作后,所有 ai 的和是多少。
//如图上所示,在第 4 块木板右侧倒水,可以淹没第 5 块和第 6 块一共 2 块木板,a4 = 2。

//例如 n = 5,每块木板高分别为 10,5,8,12,6。sum 记录最后的结果,初始为 0。
//第 1 块木板高 10,栈为空,10 入栈;
//第 2 块木板高 5,栈顶为 10,5 入栈;
//第 3 块木板高 8,栈顶 5 比 8 小,删除栈顶,a2 为 3 - 2 - 	1 = 0,sum = 0。此时栈顶为 10,8 入栈;
//第 4 块木板高 12,栈顶 8 比 12 小,删除栈顶,a 3为 4 - 3 	-1 = 0,sum = 0。此时栈顶为 10 比 12 小,继续删	除栈顶,
//a1 为 4 - 1 - 1 = 2,sum = 2。此时栈为空	,12 入栈。
//第 5 块木板高 6,栈顶为 12,把 6 加入栈中。
//遍历结束后,栈不为空,依次删除栈顶,当前位置为 n + 1,栈顶是第 5 个元素 6,a5 为 6 - 5 - 1 = 0,sum = 2。
//删除栈顶,此时栈顶是第 4 个元素 12,a 4为 6 - 4 - 1 = 1,sum = 3。此时栈为空,得到 sum 为 3,程序结束。

#include<iostream>
#include<cassert>
using namespace std;
class Node {
public:
    int id, height;
};
template<class Type> class Stack {
private:
    Type *urls;
    int max_size, top_index;
public:
    Stack(int length_input) {
        urls = new Type[length_input];
        max_size = length_input;
        top_index = -1;
    }
    ~Stack() {
        delete[] urls;
    }
    bool push(const Type &element) {
        if (top_index >= max_size - 1) {
            return false;
        }
        top_index++;
        urls[top_index] = element;
        return true;
    }
    bool pop() {
        if (top_index < 0) {
            return false;
        }
        top_index--;
        return true;
    }
    Type top() {
        assert(top_index >= 0);
        return urls[top_index];
    }
    bool empty() {
        if (top_index < 0) {
            return true;
        } else {
            return false;
        }
    }
};
int main() {
    //n表示有n块木板,ans用来记录最后的结果
    int n, ans = 0;
    cin>>n;
    //定义node类型的栈stack长度为n
    Stack<Node> stack(n);
    Node temp;
    for(int i = 1; i <= n;i++){
        //C++中->左侧一定是指针,.的左侧是实体
        cin>>temp.height;
        temp.id = i;
         while(!stack.empty() && stack.top().height <= temp.height){
            ans = ans + i - stack.top().id - 1;
            stack.pop();
        }
        stack.push(temp);
    }
    while(!stack.empty()){
       // stack.pop();
         ans = ans + n + 1 - stack.top().id - 1;
            stack.pop();
    }
   cout<<ans<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值