poj_3250 单调栈
题目大意
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 单调栈的更多相关文章
- BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8748 Solved: 3835[Submi ...
- BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]
4453: cys就是要拿英魂! Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 90 Solved: 46[Submit][Status][Discu ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- poj 2559 Largest Rectangle in a Histogram - 单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19782 ...
- bzoj1510: [POI2006]Kra-The Disks(单调栈)
这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...
- 洛谷U4859matrix[单调栈]
题目描述 给一个元素均为正整数的矩阵,上升矩阵的定义为矩阵中每行.每列都是严格递增的. 求给定矩阵中上升子矩阵的数量. 输入输出格式 输入格式: 第一行两个正整数n.m,表示矩阵的行数.列数. 接下来 ...
- POJ3250[USACO2006Nov]Bad Hair Day[单调栈]
Bad Hair Day Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17774 Accepted: 6000 Des ...
- CodeForces 548D 单调栈
Mike and Feet Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Subm ...
随机推荐
- 编译安装PHP7并安装Redis扩展Swoole扩展(未实验)
用PECL自动安装Redis扩展.Swoole扩展 pecl install redis pecl install swool 编译安装PHP7并安装Redis扩展Swoole扩展 在编译php7的机 ...
- c++,当const char*为0时,不能将其直接赋给string
下面程序会崩溃: const char* t_objName = (obj!=NULL)?obj->getName(): 0; string objName=t_objName; cout< ...
- linux下利用shell脚本和mysqldump热备份和恢复mysql
对mifeng数据库进行每周六3:33完全热备份,并可以完全恢复! 一.先建立备份脚本 #vi /mifengbackup/backup.sh #!bin/bash cd /mifengbackup ...
- centos中安装openjdk
openjdk的java环境还是简单好用,至于其他的,现在又用不到,为啥要费事安装它们? 步骤: 1.yum search java | grep jdk [root@noi ~]# yum sear ...
- 解决:Access denied for user 'root'@'localhost' (using password: YES)
症状: 重新安装了MySQL,改变了root的密码,因此,在java代码中修改了某个DatabaseConnectionImpl的DBPASSWORD 在java中写了一些代码测试MySQL的插入和查 ...
- hive优化总结
一.表设计 合理分表 合理设计表分区,静态分区.动态分区 二.扫描相关 1.谓词下推(Predicate Push Down) 2.列裁剪(Column Pruning) 在读数据的时候,只关心感兴趣 ...
- redis使用场景介绍
一:缓存——热数据 热点数据(经常会被查询,但是不经常被修改或者删除的数据),首选是使用redis缓存,毕竟强大到冒泡的QPS和极强的稳定性不是所有类似工具都有的,而且相比于memcached还提供了 ...
- Git中保存用户名和密码
每次操作都需要输入用户名和密码感觉很繁琐,解决方法,在本地的工程文件夹的.git下打开config文件添加: [credential] helper = store 再输入一次用户名密码后就可 ...
- 分享8个常用的jQuery焦点图插件
现在web网页jquery应用越来越广泛,目前几乎每一个WEB项目都在使用jQuery,因为jQuery插件实在太丰富,尤其是一些图片滑块插件和jQuery焦点图插件,更是多如牛毛,很多初学者只需稍微 ...
- 【转载】PHP 常用的header头部定义汇总
header() 函数向客户端发送原始的 HTTP 报头. 认识到一点很重要,即必须在任何实际的输出被发送之前调用 header() 函数(在 PHP 4 以及更高的版本中,您可以使用输出缓存来解决此 ...