洛谷 P1823 [COI2007] Patrik 音乐会的等待 题解
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 音乐会的等待 题解的更多相关文章
- 洛谷 P1823 [COI2007] Patrik 音乐会的等待
洛谷 P1823 [COI2007] Patrik 音乐会的等待 洛谷传送门 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A ...
- 洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)
洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1333275 这个题不是很 ...
- 洛谷P1823 [COI2007] Patrik 音乐会的等待
https://www.luogu.org/problemnew/show/P1823 自己只会一个log的 设取的人的位置分别是l,r(l<r) 这个做法大概是考虑枚举r,设法对于每个r求出有 ...
- 洛谷 1823 [COI2007] Patrik 音乐会的等待
[题解] 维护一个单调栈即可. 但是因为有相同身高的存在,所以要稍微考虑下相同身高的处理.因为这个卡了一下下QAQ... #include<cstdio> #include<algo ...
- P1823 [COI2007] Patrik 音乐会的等待 单调栈 洛谷luogu
题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...
- [COI2007] Patrik 音乐会的等待 (单调栈,模拟)
题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...
- luoguP1823 [COI2007] Patrik 音乐会的等待
题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...
- [COI2007] Patrik 音乐会的等待 单调栈
Code: #include<cstdio> #include<algorithm> #include<iostream> #include<cstring& ...
- [洛谷P1823]音乐会的等待 题解(单调栈)
[洛谷P1823]音乐会的等待 Description N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没 ...
随机推荐
- python3与Excel的完美结合
https://segmentfault.com/a/1190000016256490 Excel 是 Windows 环境下流行的.强大的电子表格应用.openpyxl 模块让 Python 程序能 ...
- Spring Cloud Alibaba学习笔记(21) - Spring Cloud Gateway 自定义全局过滤器
在前文中,我们介绍了Spring Cloud Gateway内置了一系列的全局过滤器,本文介绍如何自定义全局过滤器. 自定义全局过滤需要实现GlobalFilter 接口,该接口和 GatewayFi ...
- 2.Vue 获取企业微信的Code并把Code发送的后台进行验证
1 . 在企业微信配置请求的页面写入下面代码 mounted() { //获取微信请求的的Code let code = this.$route.query.code; if (code) { thi ...
- C# vb .net实现饱和度调整特效滤镜
在.net中,如何简单快捷地实现Photoshop滤镜组中的饱和度调整呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一 ...
- MVC4 部署 could not load file or assembly system.web.http.webhost 或是其它文件出误
自从VS2010发布之后使用它来做开发的程序员越来越多,其中很多人使用了MVC来作为新的开发框架,但是在系统部署的时候我们也遇到诸多问题,因为目前大多数windows服务器采用的还是Windows S ...
- 关于ES6的对象扩展运算符
对象的扩展运算符(...),用于取出参数对象中的所有可遍历属性,然后拷贝到当前对象之中 对象扩展运算符: 1. 复制对象 let obj1 = { x: 1, y: 2, z: 3 } let obj ...
- C++线程同步与互斥之互斥体
抢红包练习 第一步:在第一个文本框中输入一个值,比如1000: 第二步:点击抢红包,同时创建3个线程,每个线程循环进行抢红包的操作,每次抢50; 第三步:使用Mutex进行线程控制,当第一个文本框中的 ...
- Qt QListWidget
以下代码是 List Widget 添加数据项的代码,一般放在构造函数即可. /*********************添加数据项*********************/ QIcon icon1 ...
- vscode编辑器自定义配置
{ //删除文件确认 "explorer.confirmDelete": false, // 主题 "workbench.iconTheme": "v ...
- 安装node.js->npm->vue
我们研究vue时,首先操作的就是vue的引用,大部分人为了方便直接在页面上引用vue.js,但是一些大型网站还是比较喜欢用vue的npm命令来安装vue并使用,之前研究vue时,研究过使用npm安装的 ...