P1823 [COI2007] Patrik 音乐会的等待

题目描述

N个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的。

写一个程序计算出有多少对人可以互相看见。

输入格式

输入的第一行包含一个整数N (1 ≤ N ≤ 500 000), 表示队伍中共有N个人。

接下来的N行中,每行包含一个整数,表示人的高度,以毫微米(等于10的-9次方米)为单位,每个人的调度都小于2^31毫微米。这些高度分别表示队伍中人的身高。

输出格式

输出仅有一行,包含一个数S,表示队伍中共有S对人可以互相看见。

输入输出样例

输入 #1

7

2

4

1

2

2

5

1

输出 #1

10

说明/提示

数据制作: @w

2018.6.29添加3组数据

【思路】

单调栈

很有意思的一道题目

【题目大意】

一个队列

两个人中间只要没有比他俩其中一个高的就可以相互看见

求能够相互看见的对数

【理智分析】

这对点能够互相看见是基于两者之间没有比他们任何一者高的基础上的

一个人能够看见最远的一个人就是两边第一个比他高的

这很显然对吧?

因为第一个比他高的之后的人就被他挡住了

(贴合实际)

然后如果这个人和一边第一个比他高的人

中间的人不一定能够全部被这个人看见

【举例】

因为:

1 1 4 5 1 4 1 9 1 9

位置8上的那个9右边能看到最远的就是位置1上的1

但是位置1到位置8之间所有的数

他不是都能够彼此看见的

比如位置5上的那个1

就不能彼此看见

因为中间有一个位置6上的4是比1高的

所以彼此看不见

看一下位置8上的9右边能够看到的数

5 4 1

很显然这是一个大向右递增的区间

因为你看到了右边第一个之后

看到的右边第二个不能够比右边第一个要低

不然就是不能够被看见的

【呼之欲出】

是不是很显然了?

这不就是单调栈吗!?

【最终思路】

上面的过程完全就是在单调栈的过程对吧

如果栈里面的栈顶元素比手上这个元素要小

那栈顶元素左边能够看到的最后一个元素就是手上这个了

再也看不到别的了

这就是1对可以互相看见

弹出就好了

然后手上这个继续和栈顶去比较

【注意】

两个一样高的人是可以相互看见的

1 1 1 1 1

这串数字里面

第一个1是可以和最后一个1相互看见的

千万不要忽略哦

然后就是怎么处理上面这种情况了

一开始我想的是暴力从栈里面取出来

计数有多少个

计完数之后再放回栈

这样就超时了两个点

这两个点我下载了一个点的测试数据看来一下

500000个一样的10

不超时才怪……

所以 可以在栈中存一个结构体

记录这个人的高度和人数

也就是和她一样高的并且在栈中位置是紧挨着的

遇到和她一样的情况只需要将其弹出

然后在弹入一个v(计数多少个人) + 1的就好了

【完整代码】

【80分暴力出栈代码】

#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
const int Max = 500005;
int a[Max];
stack<int>s;
int main()
{
int n;
cin >> n;
for(register int i = 1;i <= n;++ i)
cin >> a[i];
int js = 0;
for(register int i = 1;i <= n;++ i)
{
int jj = 0;
while(!s.empty() && a[i] >= s.top())
{
if(a[i] == s.top())
{
while(!s.empty() && s.top() == a[i])
s.pop(),jj ++,js ++;
}
else
{
s.pop();
js ++;
}
}
if(!s.empty())
js ++;
while(jj --)
s.push(a[i]);
s.push(a[i]);
}
cout << js << endl;
return 0;
}

【AC代码】

#include<iostream>
#include<cstdio>
#include<stack>
#define int long long
using namespace std;
const int Max = 500005;
struct node
{
int h;
int v;
}a[Max];
stack<node>s;
signed main()
{
// freopen("music.in","r",stdin);
int n;
cin >> n;
for(register int i = 1;i <= n;++ i)
cin >> a[i].h,a[i].v = 1;
int ans = 0;
for(register int i = 1;i <= n;++ i)
{
while(!s.empty() && a[i].h > s.top().h)
{
ans += s.top().v;
s.pop();
}
if(!s.empty() && a[i].h == s.top().h)
{
node qwq = s.top();
ans += s.top().v;
s.pop();
if(!s.empty())
ans ++;
s.push((node){qwq.h,qwq.v + 1});
}
else
{
if(!s.empty())
ans ++;
s.push(a[i]);
}
}
cout << ans << endl;
return 0;
}

洛谷 P1823 [COI2007] Patrik 音乐会的等待 题解的更多相关文章

  1. 洛谷 P1823 [COI2007] Patrik 音乐会的等待

    洛谷 P1823 [COI2007] Patrik 音乐会的等待 洛谷传送门 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A ...

  2. 洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)

    洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1333275 这个题不是很 ...

  3. 洛谷P1823 [COI2007] Patrik 音乐会的等待

    https://www.luogu.org/problemnew/show/P1823 自己只会一个log的 设取的人的位置分别是l,r(l<r) 这个做法大概是考虑枚举r,设法对于每个r求出有 ...

  4. 洛谷 1823 [COI2007] Patrik 音乐会的等待

    [题解] 维护一个单调栈即可. 但是因为有相同身高的存在,所以要稍微考虑下相同身高的处理.因为这个卡了一下下QAQ... #include<cstdio> #include<algo ...

  5. P1823 [COI2007] Patrik 音乐会的等待 单调栈 洛谷luogu

    题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...

  6. [COI2007] Patrik 音乐会的等待 (单调栈,模拟)

    题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...

  7. luoguP1823 [COI2007] Patrik 音乐会的等待

    题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...

  8. [COI2007] Patrik 音乐会的等待 单调栈

    Code: #include<cstdio> #include<algorithm> #include<iostream> #include<cstring& ...

  9. [洛谷P1823]音乐会的等待 题解(单调栈)

    [洛谷P1823]音乐会的等待 Description N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没 ...

随机推荐

  1. java之struts2之异常处理

    1.在应用项目中,异常的出现时很正常的.而且项目上线后发生异常也很正常的.那么需要对这些异常有相应的处理机制,以便客户能够看你到更加友好的界面.Struts2中提供了异常处理机制. 2.Struts中 ...

  2. ssh免秘钥

    用过好几次免秘钥,但是每次都会忘了应该把copy谁的公钥到另外用户的.ssh文件夹 这里专门记录一次 注意点: A要使用ssh免密登录到B用户下(可以使远程服务器),就把A的用户下的.ssh文件的id ...

  3. python-socket并发-解决tcp粘包问题

    粘包问题 tcp协议才会有粘包问题,udp协议没有粘包问题. 因为tcp协议是将需要传输的内容先读入缓存里,然后在一点点传,受接收方字符限制,并不能一次传输完成,第二次就会将第一次剩下的部分+第二次的 ...

  4. 2019年北航OO第三次博客总结

    一.JML语言理论基础及其工具链 1. JML语言理论基础 JML是用于对Java程序进行规格化设计的一种表示语言,是一种行为接口规格语言(Behavior Interface Specificati ...

  5. 过渡属性transition

    过渡属性:使元素变化过程可见 transition: all 1s;元素所有变化过程都可见 transition: 1s;元素所有变化过程都可见 transition: 指定属性 2s 1s;指定属性 ...

  6. WebSocket转载

    目录   概述  WebSocket 客户端  WebSocket 服务端  WebSocket 代理  FAQ  完整示例  资料 概述 WebSocket 是什么? WebSocket 是一种网络 ...

  7. hive介绍及架构设计

    hive介绍及架构设计 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们知道MapReduce和Spark它们提供了高度抽象的编程接口便于用户编写分布式程序,它们具有极好的扩展性 ...

  8. mysql字典取值,列表包含

    SELECT * FROM e where JSON_CONTAINS(json_extract(scope_detail, '$.shop'), '001');

  9. 移动App性能评测与优化-Android内存测试 ,DVM原理

    常见的测试方法包括Monkey/UIAutomator类的常规压力测试,大数据/操作的峰值压力测试,长时间运行的稳定性测试等. 前提: 测试准备:版本是纯净版本,不应该附加多余的log和调试用组件. ...

  10. 圆柱模板行业B2B站点打造MIP推送+熊掌号推送+历史普通推送插件

    最近因为做聚合页面http://zhimo.yuanzhumuban.cc/hotkey/list-951.html  内部站点关键词拥有5万的行业词库,所以这么多搜索词库,如何让百度第一时间抓取呢? ...