题目大意

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. 编译安装PHP7并安装Redis扩展Swoole扩展(未实验)

    用PECL自动安装Redis扩展.Swoole扩展 pecl install redis pecl install swool 编译安装PHP7并安装Redis扩展Swoole扩展 在编译php7的机 ...

  2. c++,当const char*为0时,不能将其直接赋给string

    下面程序会崩溃: const char* t_objName = (obj!=NULL)?obj->getName(): 0; string objName=t_objName; cout< ...

  3. linux下利用shell脚本和mysqldump热备份和恢复mysql

    对mifeng数据库进行每周六3:33完全热备份,并可以完全恢复! 一.先建立备份脚本 #vi /mifengbackup/backup.sh #!bin/bash cd /mifengbackup ...

  4. centos中安装openjdk

    openjdk的java环境还是简单好用,至于其他的,现在又用不到,为啥要费事安装它们? 步骤: 1.yum search java | grep jdk [root@noi ~]# yum sear ...

  5. 解决:Access denied for user 'root'@'localhost' (using password: YES)

    症状: 重新安装了MySQL,改变了root的密码,因此,在java代码中修改了某个DatabaseConnectionImpl的DBPASSWORD 在java中写了一些代码测试MySQL的插入和查 ...

  6. hive优化总结

    一.表设计 合理分表 合理设计表分区,静态分区.动态分区 二.扫描相关 1.谓词下推(Predicate Push Down) 2.列裁剪(Column Pruning) 在读数据的时候,只关心感兴趣 ...

  7. redis使用场景介绍

    一:缓存——热数据 热点数据(经常会被查询,但是不经常被修改或者删除的数据),首选是使用redis缓存,毕竟强大到冒泡的QPS和极强的稳定性不是所有类似工具都有的,而且相比于memcached还提供了 ...

  8. Git中保存用户名和密码

    每次操作都需要输入用户名和密码感觉很繁琐,解决方法,在本地的工程文件夹的.git下打开config文件添加: [credential]     helper = store 再输入一次用户名密码后就可 ...

  9. 分享8个常用的jQuery焦点图插件

    现在web网页jquery应用越来越广泛,目前几乎每一个WEB项目都在使用jQuery,因为jQuery插件实在太丰富,尤其是一些图片滑块插件和jQuery焦点图插件,更是多如牛毛,很多初学者只需稍微 ...

  10. 【转载】PHP 常用的header头部定义汇总

    header() 函数向客户端发送原始的 HTTP 报头. 认识到一点很重要,即必须在任何实际的输出被发送之前调用 header() 函数(在 PHP 4 以及更高的版本中,您可以使用输出缓存来解决此 ...