最后更新于2019.1.23

A Famous City

?戳这里可以前往原题

Problem Description

After Mr. B arrived in Warsaw, he was shocked by the skyscrapers and took several photos. But now when he looks at these photos, he finds in surprise that he isn’t able to point out even the number of buildings in it. So he decides to work it out as follows:

  • divide the photo into n vertical pieces from left to right. The buildings in the photo can be treated as rectangles, the lower edge of which is the horizon. One building may span several consecutive pieces, but each piece can only contain one visible building, or no buildings at all.
  • measure the height of each building in that piece.
  • write a program to calculate the minimum number of buildings.

    Mr. B has finished the first two steps, the last comes to you.

Input

Each test case starts with a line containing an integer n (1 <= n <= 100,000). Following this is a line containing n integers - the height of building in each piece respectively. Note that zero height means there are no buildings in this piece at all. All the input numbers will be nonnegative and less than 1,000,000,000.

Output

For each test case, display a single line containing the case number and the minimum possible number of buildings in the photo.

Sample Input

3

1 2 3

3

1 2 1

Sample Output

Case 1: 3

Case 2: 2

题目大意:

将一张照片从左到右分为N个垂直部分。照片中的建筑物可以被视为矩形,一栋建筑可以跨越几个连续的部分,但每个部分只能包含一个可见的建筑,或者根本没有建筑。根据每个部分的高度,求出照片中最少建筑物数量

解题思路:

考虑最优情况,及每一种高度就只有一个建筑物,则最少建筑物数量及等于高度的种数。

根据高的建筑物覆盖低的建筑物原则,也就是说,如果两个矩形之间的所有建筑物的高度都大于等于这两个矩形,且这两个矩形高度相等,我们就可以把这两个矩形视为同一个建筑物。反过来,如果这两个矩形之间的建筑物中出现了更低的矩形,那么这两个就一定不能连成一个建筑物。

推广上面的结论:

1、如果所有的矩形高度维持从小到大的顺序,则最少建筑物数量及等于高度的种数。

2、如果出现了比上一个矩形更低的矩形,则上一个矩形所对应的建筑物不能再与后面的建筑物连成一个,则我们可以结算掉前面已经出现的矩形中,高于新加入的矩形的个数。

也就是说,我们需要把不断递增的序列保存下来,然后维护这个序列保持严格递增,即可得到答案,即维护一个单调栈。

下面是AC代码

#include <bits/stdc++.h>

using namespace std;

stack<int> st;//栈

int main()
{
ios::sync_with_stdio(false); int n;
int cases=1;
int answer;
while (cin>>n)
{
answer=0;
int temp;
//由于我们最后计算个数时必然会把栈内的数据全部弹出,则不需要清空栈
while (n--)
{
cin>>temp;
if (st.empty())//如果栈内为空,则直接推入栈
{
st.push(temp);
continue;
}
//如果出现比栈内所有值都高的一个值,则可以直接入栈(由于我们维护的是单调栈,所以栈顶的元素一定是最大的,所以只需要比较栈顶的元素)
if (temp>st.top())
{
st.push(temp);
}
else if (temp<st.top())//反之则把大于新的数据的值都从栈中弹出
{
while ((!st.empty()) && (st.top()>temp))
{
answer++;
st.pop();
}
if (st.empty())//如果已经弹空
{
st.push(temp);
continue;
}
if (st.top()!=temp)//如果将要入栈的值与上一个值发生重复,则不需要压入栈,这里判断的是不重复的情况
{
st.push(temp);
}
}
}
while(!st.empty())//结算栈中剩下的部分
{
if(st.top())//这里是此题的一个坑,因为可能出现高度为0的情况,而0是没有建筑的
{
answer++;
}
st.pop();
}
cout<<"Case "<<cases<<": "<<answer<<endl;
cases++;
}
return 0;
}

HDU-4252 A Famous City(单调栈)的更多相关文章

  1. HDOJ 4252 A Famous City 单调栈

    单调栈: 维护一个单调栈 A Famous City Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  2. hdu 4252 A Famous City

    题意:一张相片上的很多建筑相互遮住了,根据高低不同就在相片上把一座高楼的可见部分作为一个矩形,并用数字描述其高度,若一张相片上的两个建筑群中间有空地,高度则为0;求最少有多少个建筑; 分析: 输入的0 ...

  3. bnuoj 25659 A Famous City (单调栈)

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=25659 #include <iostream> #include <stdio.h ...

  4. HDU 5875 H - Function 用单调栈水过了

    http://acm.hdu.edu.cn/showproblem.php?pid=5875 单调栈,预处理to[i]表示第一个比a[i]小的数字,一直跳就可以. 这题是数据水而已. 这里学习下单调栈 ...

  5. HDU 4923 Room and Moor (单调栈)

    题意: 给你一个A数列,让你求一个单调递增的B数列(0<=bi<=1),使得sum{(ai-bi)^2}最小. 思路: 很明显,如果A = 0...01...1,那么bi=ai即可. 可以 ...

  6. hdu 5696 区间的价值 单调栈+rmq

    区间的价值 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem D ...

  7. hdu 4923 Room and Moor (单调栈+思维)

    题意: 给一个0和1组成的序列a,要构造一个相同长度的序列b.b要满足非严格单调,且 值为0到1的实数.最后使得  sum((ai-bi)^2)最小. 算法: 首先a序列開始的连续0和末尾的连续1是能 ...

  8. HDU - 5033: Building(单调栈 ,求一排高楼中人看楼的最大仰角)

    pro:现在在X轴上有N个摩天大楼,以及Q个人,人和大楼的坐标各不相同,保证每个人左边和右边都有楼,问每个人能看到天空的角度大小. sol:不难想到就是维护凸包,此题就是让你模拟斜率优化,此处没有斜率 ...

  9. HDU 5033 Building(单调栈)

    HDU 5033 Building(单调栈) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033 Description Once upon a ti ...

随机推荐

  1. List.remove()的使用注意

    不使用forEach的循环 使用forEach循环 参考 今天修改一个bug,需要取一个List和一个Set的交集,使用了双重循环.想着提高循环效率,每加入一个交集中的元素,就将List中的元素删除, ...

  2. 解密JDK8 枚举

    写一个枚举类 1 2 3 4 5 6 public enum Season { SPRING, SUMMER, AUTUMN, WINTER } 然后我们使用javac编译上面的类,得到class文件 ...

  3. Redis:slave flush old data造成实例不可用

    一.问题描述 2019-02-22凌晨02:42分前后,收到集群中 [10.32.52.8:6500] 实例不可用告警,登陆管理界面查看此实例在正常运行状态,期间未出现机器宕机或实例直接挂掉的现象. ...

  4. vmware增加新硬盘无需重启生效

    echo "scsi add-single-device 2 0 2 0" > /proc/scsi/scsi # echo "scsi add-single-de ...

  5. 开始使用Github

     Gather ye rosebuds while ye may 我自己也是刚开始使用github没几天,写得不好我就写自己常用的吧 2015年9月20日下午3:19更新知乎上这个答案写得好多了

  6. 在虚拟机单机部署OpenStack Grizzly

    安装过程 安装Ubuntu 我手头有的是Ubuntu Server 12.04 64位版,就直接用了,默认安装即可,配置的时候很简单,如下 内存:1G 硬盘:20G 处理器:2 网络:NAT 装好以后 ...

  7. 自然语言处理NLTK之入门

    环境:window10 + python3 一.安装NLTK pip install nltk # 或者 PyCharm --> File --> Settings --> Proj ...

  8. Spring事务Transactional和动态代理(二)-cglib动态代理

    系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...

  9. Java设计模式二

    今天谈的是工厂模式,该模式用于封装和对对象的创建,万物皆对象,那么万物又是产品类,如一个水果厂生产三种水果罐头,我们就可以将这三种水果作为产品类,再定义一个接口用来设定对水果罐头的生成方法,在工厂类中 ...

  10. 安装skimage和cv2

    因为第一次接触这个,所以当时安装的时候,也不是很清楚,现在明白了,记录一下,下次别入坑了. 1.安装skimage模块 skimage的全称是:scikit-image 如果说是这样安装,提示我不成功 ...