GDUT 积木积水(栈)

题意

Description

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

Input

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

Output

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

Sample Input

1

11

6 2 2 4 2 0 3 4 4 5 1

Sample Output

19

思路

数据范围是10^6,显然不能O(n^2)。

不自然的就想到了栈。

维护一个递减的栈。

如果,当前列比栈顶列低,那就入栈。

否则,就一直出栈,直至栈顶高于当前列。

理由是显然的,对于两个相对高些的列,它们之间的较低列显然是没用的。

最后,所有列都进行过后,对栈里元素依次出栈,并记录它们之间的矩形面积,再减去它们之间的方格总数,既是最终的答案。

代码

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <stack>

using namespace std;
#define LL long long

LL d[1000009], g[1000009];

int main()
{
    int T, n;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        for(int i=0; i<n; i++)
            scanf("%d", &d[i]);

        g[0] = d[0];
        for(int i=1; i<n; i++)
            g[i] = g[i-1] + d[i];
        stack<int> s;

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

            if(s.empty())
                ans += (i-t-1)*d[t]-(g[i-1]-g[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]-(g[i-1]-g[t]);
                i = t;
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}
时间: 2024-10-25 10:30:57

GDUT 积木积水(栈)的相关文章

ACM学习历程—广东工业大学2016校赛决赛-网络赛E 积木积水(最值问题 || 动态规划)

题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=4 这个题目自然会考虑到去讨论最长或者最短的板子. 笔上大概模拟一下的话,就会知道,假设最长的板子是r,0和n+1位置上都是高度为0的板子,那么对于[0, r-1]中的最长板子rr,rr到r这一短应该都是被深度为a[rr]的水覆盖.同样的[0, rr-1]中的最长板子rrr,rrr到rr这一段应该是被a[rrr]覆盖,以此类推可以搞定r的前面一段,同理搞定后一段. 关于最值这一块,

GDUT-校赛-积水积木

Problem E: 积木积水 Description 现有一堆边长为1的已经放置好的积木,小明(对的,你没看错,的确是陪伴我们成长的那个小明)想知道当下雨天来时会有多少积水.小明又是如此地喜欢二次元,于是他把这个三维的现实问题简化成二维的问题.设雨量无穷.积木不透水.积木间无缝连接,问在这个二次元的世界里,已放置好的积木会有多少单位的积水量? Input 第一行包含一个整数T(T≤100),表示接下来的测试样例个数. 每个测试样例有两行组成: 第一行包含一个整数N(N≤1e6),表示积木的列数

广工2016校赛决赛

重现补的题目. Problem A: Krito的讨伐 思路:不要求一次性杀光一个节点里面的所有怪物. 所以我们可以用一个优先队列.优先去杀那些我们当前可以挑战的,然后注意下处理一个房间可能有多个怪物或者无怪物.当我们杀完第x个房间的怪物时候,那么就把x的下一层的怪物加入队列,如果x的下一层出现了空房间[即房间不存在怪物],那么再把该房间当做新的x,继续加入新x的下一层直到出现了有怪物的房间位置. #define _CRT_SECURE_NO_DEPRECATE #include<iostrea

2016广东工业大学校赛 E题 GDUT-oj1173

Problem E: 积木积水 Description 现有一堆边长为1的已经放置好的积木,小明(对的,你没看错,的确是陪伴我们成长的那个小明)想知道当下雨天来时会有多少积水.小明又是如此地喜欢二次元,于是他把这个三维的现实问题简化成二维的问题.设雨量无穷.积木不透水.积木间无缝连接,问在这个二次元的世界里,已放置好的积木会有多少单位的积水量? Input 第一行包含一个整数T(T≤100),表示接下来的测试样例个数. 每个测试样例有两行组成: 第一行包含一个整数N(N≤1e6),表示积木的列数

七方件业金离以提领前群约会ODjdidtlwfWv

为了从不同环节,尤其与广大使用人群直接关系的环节反映质量状况,对共享自行车投放点.运营仓库.生产企业等不同环节的产品抽查,覆盖了共享自行车从成品出厂到待投放的关键环节. 该负责人称,根据新车投放情况,结合共享自行车行业市场占有分布特点,本次重点抽查了摩拜.ofo.Hellobike三个品牌的产品,占本次抽查批次总数的83.3%.其中,在天津.无锡.武汉.广州.深圳.东莞6个城市抽查了9批次摩拜产品,占产品抽查批次总数的37.5%,抽查批次合格率88.9%,抽查不合格的1批次产品为待投放于广州市的

【数据结构】用两个栈实现队列

惯例.看题: 题目:用两个栈实现一个队列.队列的声明如下.请实现它的两个函数appendTail和deleteHead,分别完成对也尾部插入节点和队列头部删除节点的功能. 队列结构:     template<typename T> class CQueue     {      public:         CQueue(void);         ~CQueue(void);                  void appendTail(const T & node);  

Stack的三种含义(数据超过栈的大小,就发生stack overflow)

非常典型的基础知识,转自http://www.ruanyifeng.com/blog/2013/11/stack.html 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈". 理解这个概念,对于理解程序的运行至关重要.容易混淆的是,这个词其实有三种含义,适用于不同的场合,必须加以区分. 含义一:数据结构 stack的第一种含义是一组数据的存放方式,特点为LIFO,即后进先出(Last in, first out). 在这种数据结构中,数据像积木那样一层层堆起来,后面加

Java之用栈实现队列

队列是一种典型的先进先出数据结构,队列的实现方式有很多种,比如数组,比如链表等,队列也可以用两个栈来实现,下面就用两个栈实现一个队列. 原理 两个栈中,一个栈用来入队,叫他入队栈,另一个栈用来出队,叫出队栈. 当入队时,我们直接把元素压入入队栈. 当出队时,分两种情况:   ①若出队栈不为空,则直接出队栈栈顶元素出栈   ②若出队栈为空,则入队栈元素依次出栈并压入出队栈,然后出队栈出栈 具体实现 知道了原理后,实现起来就很简单啦,这里我们借助JDK中的java.util.stack类来作为我们队

Stack栈的三种含义

理解stack栈对于理解程序的执行至关重要.easy混淆的是,这个词事实上有三种含义,适用于不同的场合,必须加以区分. 含义一:数据结构 stack的第一种含义是一组数据的存放方式,特点为LIFO,即后进先出(Last in,first out). 在这样的数据结构中,数据像积木那样一层层堆起来,后面添?的数据就放在最上层.使用的时候,最上层的数据第一个被用掉,这就叫做"后进先出". 与这样的结构配套的是以下几种特定的方法: (1)push:在最顶层添?数据 (2)pop:返回并移除最