洛谷 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 音乐会的等待 题解的主要内容,如果未能解决你的问题,请参考以下文章

洛谷——P1823 音乐会的等待

洛谷 P1823 音乐会的等待

[COI2007] [luogu P1823] Patrik 音乐会的等待 解题报告 (单调栈)

洛谷 P1053 音乐会的等待 解题报告

P1823 音乐会的等待

音乐会的等待-题解