洛谷 P1823 音乐会的等待 题解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P1823 音乐会的等待 题解相关的知识,希望对你有一定的参考价值。
此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。
题目链接:https://www.luogu.org/problem/show?pid=1823
题目描述
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
分析:(参考了@hychychyc 的题解)
此题用单调栈来做,构建一个单调递减的栈。
一旦出现了一个比栈顶大的元素,那么该元素就可以“看到”栈内第一个比它大的元素之前的所有元素。
这时就把栈内元素依次弹出,直到栈顶元素比该元素大(或栈被弹空)再将该元素入栈。
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<stack> 5 6 using namespace std; 7 int num[500005]; 8 //数组模拟一个栈 9 int main() 10 { 11 int n,x,top = 1,ans = 0,tmp; 12 //tmp记录当前相等的元素个数 13 scanf("%d%d",&n,&x); 14 num[1] = x; 15 for(int i = 2;i <= n;i ++) 16 { 17 tmp = 1; 18 scanf("%d",&x); 19 if(x >= num[top]) 20 { 21 while(x > num[top] && top > 0) 22 top --,ans ++; 23 while(x == num[top] && top > 0) 24 {//相等情况 25 tmp ++; 26 top --,ans ++; 27 } 28 } 29 if(top != 0) ans ++; 30 //如果栈内还有元素,即比x大的第一个元素,两者也可以相互看到 31 top += tmp;//把相等的元素加回去 32 num[top] = x; 33 } 34 printf("%d\n",ans); 35 return 0; 36 }
以上是关于洛谷 P1823 音乐会的等待 题解的主要内容,如果未能解决你的问题,请参考以下文章