题目大意

N头牛排成一列,每头牛A都能看到它前面比它矮的牛i,若前面有一个比他高的牛X,则X之前的牛j,A都无法看到。给出N头牛的高度,求出这N头牛可以看到牛的数目的总数。

题目分析

画图之后,可以很容易看出是典型的单调栈问题。单调栈问题中栈元素一般有两个属性:一是牛的索引位置,二是牛的高度。每次得到一个牛index的高度height之后,都和栈顶元素进行比较,若height > stack[top].height 则直接将(新牛的高度height,新牛的索引index)入栈,否则,弹栈,直到栈顶元素stack[top].height < height,再将(新牛的高度height,新牛的索引index)入栈。 
    在牛A被出栈的时候,可以获得牛A能够看到的牛的个数(即新入栈的牛B的索引index_b - 牛A的索引index_a)。最后记得清空栈元素来获得所有值。

实现(c++)

可以不使用单调栈

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<vector>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<set>
#include<map>
#include<functional>
#include<algorithm>
using namespace std;
const int kMax = 80005; //height 数组
int height[kMax]; //从i点向左看,第一个高度等于或者大于height[i]的数组下标
int higher_index[kMax]; long long int solve(int n){
int j;
long long result = 0;
for (int i = 0; i < n; i++){
j = i - 1;
while (j >= 0 && height[j] < height[i]){
j = higher_index[j];
}
higher_index[i] = j;
result += (i - j - 1);
}
return result;
}
int main(){
int n;
scanf("%d", &n);
//题目要求从左向右看,将数组颠倒,然后换个方向,从右向左看,结果是一样的
for (int i = n - 1; i >= 0; i--){
scanf("%d", &height[i]);
}
long long int result = solve(n);
printf("%lld\n", result);
return 0;
}

使用单调栈

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX_COW_NUM 80005
int st[MAX_COW_NUM][2];
int gCanSeeNum[MAX_COW_NUM]; int main(){
int n;
scanf("%d", &n);
int height, top = -1;
long long sum = 0;
for (int i = 0; i < n; i++){
scanf("%d", &height);
while (top >= 0 && st[top][1] <= height){
gCanSeeNum[st[top][0]] = i - st[top][0] - 1;
sum += gCanSeeNum[st[top][0]];
top--;
}
top++;
st[top][0] = i;
st[top][1] = height;
}
while (top >= 0){
gCanSeeNum[st[top][0]] = n - st[top][0] - 1;
sum += gCanSeeNum[st[top][0]];
top--;
}
printf("%lld\n", sum);
return 0;
}

 使用单调栈2

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<vector>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<set>
#include<map>
#include<functional>
#include<algorithm>
using namespace std;
const int kMax = 80005; //height 数组
int height[kMax];
int mon_stack[kMax];
long long int solve(int n){
int top = -1;
long long result = 0;
for (int i = 0; i < n; i++){
while (top >= 0 && height[mon_stack[top]] < height[i]){
top--;
}
if (top < 0)
result += i;
else
result += (i - mon_stack[top] - 1);
mon_stack[++top] = i;
}
return result;
}
int main(){
int n;
scanf("%d", &n);
//题目要求从左向右看,将数组颠倒,然后换个方向,从右向左看,结果是一样的
for (int i = n - 1; i >= 0; i--){
scanf("%d", &height[i]);
}
long long int result = solve(n);
printf("%lld\n", result);
return 0;
}

poj_3250 单调栈的更多相关文章

  1. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

  2. BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]

    4453: cys就是要拿英魂! Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 46[Submit][Status][Discu ...

  3. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  4. poj 2559 Largest Rectangle in a Histogram - 单调栈

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19782 ...

  5. bzoj1510: [POI2006]Kra-The Disks(单调栈)

    这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...

  6. BZOJ1057[ZJOI2007]棋盘制作 [单调栈]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...

  7. 洛谷U4859matrix[单调栈]

    题目描述 给一个元素均为正整数的矩阵,上升矩阵的定义为矩阵中每行.每列都是严格递增的. 求给定矩阵中上升子矩阵的数量. 输入输出格式 输入格式: 第一行两个正整数n.m,表示矩阵的行数.列数. 接下来 ...

  8. POJ3250[USACO2006Nov]Bad Hair Day[单调栈]

    Bad Hair Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17774   Accepted: 6000 Des ...

  9. CodeForces 548D 单调栈

    Mike and Feet Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Subm ...

随机推荐

  1. tsung 学习

    tsung简介: —  Tsung是开源的基于Erlang语言开发的多协议分布式压力测试工具,它能用来压力测试HTTP, WebDAV, SOAP, PostgreSQL, MySQL, LDAP 和 ...

  2. 常用RGB颜色表

      作者:张家珩2005-12-02 20:51分类:默认分类     R G B 值   R G B 值   R G B 值 黑色 0 0 0 #000000 黄色 255 255 0 #FFFF0 ...

  3. @Autowired和@Resource装配

    从Spring2.5開始就能够使用注解自己主动装配Bean的属性. 使用注解自己主动装配与XML中使用autowire属性自己主动装配并没有太大区别. Spring容器默认禁用注解装配. 所以在基于注 ...

  4. Java中RunTime类介绍

    Runtime 类代表着Java程序的运行时环境,每个Java程序都有一个Runtime实例,该类会被自动创建,我们可以通过Runtime.getRuntime() 方法来获取当前程序的Runtime ...

  5. 父级和 子集 controller 之间的通讯

    在同个 angular.js 应用的控制器之间进行通信可以有很多种不同的方式,本文主要讲两种: 基于scope继承的方式 基于event传播的方式 基于scope继承的方式 最简单的让控制器之间进行通 ...

  6. Hadoop知识汇总

    Hadoop的两大功能:海量数据存储和海量数据分析 Hadoop2的三大核心组件是:HDFS.MapperReducer和yarn 1.HDFS:分布式文件系统海量数据存储 2.MapperReduc ...

  7. Sql 常用的语句实例与代码

    在学习SQL的时候,本来预计花三天的时候掌握MS SQL这些基础,现在争取提前一天看完.总结沉底下来,其实也没有多少东西: 1.程序初始化前,先连接数据库 MFC程序中添加记录的代码: [cpp] v ...

  8. shell脚本 批量转换目录下文件编码

    发布:JB01   来源:脚本学堂     [大 中 小] 分享一例shell脚本,实现可以批量转换目录下的文件编码,很实用的一个小shell,有需要的朋友参考下.原文地址:http://www.jb ...

  9. nyoj746 整数划分(四)

    整数划分(四) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近遇到 ...

  10. Ubuntu/Debian交叉编译安装ARM平台版本的ffmpeg

    1 准备工作 (1)libmp3lame库 下载:    wget http://downloads.sourceforge.net/lame/lame-3.99.tar.gz 解压 编译:./con ...