广工校赛决赛Problem E: 积木积水

描述:
现有一堆边长为1的已经放置好的积木,小明(对的,你没看错,的确是陪伴我们成长的那个小明)想知道当下雨天来时会有多少积水。小明又是如此地喜欢二次元,于是他把这个三维的现实问题简化成二维的问题。设雨量无穷、积木不透水、积木间无缝连接,问在这个二次元的世界里,已放置好的积木会有多少单位的积水量?

输入:
第一行包含一个整数T(T≤100),表示接下来的测试样例个数。 每个测试样例有两行组成: 第一行包含一个整数N(N≤1e6),表示积木的列数; 第二行包含N个整数Ai(Ai≤1e6),表示第i列积木的个数。

输出
每个样例输出一行,包含一个整数,为题目所求。

sample input
1
11
6 2 2 4 2 0 3 4 4 5 1

sample output
19

求有多少积水,递减栈做就好

#include <cstdio>
#include <iostream>
#include <cstring>
#include <stack>
//维护一个递减栈
using namespace std;
long long d[1000005];
long long num[1000005];
using namespace std;
int main (void)
{
    int t,n;
    cin>>t;
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
        scanf("%lld",&d[i]);
        }
        num[0]=d[0];
        for(int i=1;i<n;i++)

        {
            num[i]=num[i-1]+d[i];
        }
        stack<int>s;

        long long ans=0;
        int t;
        for(int i=0;i<n;i++)
        {
            if(s.empty())
            {
                s.push(i);
                continue;
            }
            while(!s.empty())
            {
                 t=s.top();
                 if(d[t]>d[i])
                    break;
                 s.pop();
            }
            if(s.empty())
            ans+=(i-t-1)*d[t]-(num[i-1]-num[t]);
            s.push(i);
         }
         if(!s.empty())
         {
            int i=s.top();
            s.pop();
            while(!s.empty()){
                int t=s.top();
                s.pop();
                ans+=(i-t-1)*d[i]-(num[i-1]-num[t]);
                i=t;
            }
         }

    printf("%lld\n",ans);
    }
    return 0;
}//有趣的栈hhh
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值