首页 > 代码库 > 洛谷 P1823 音乐会的等待 题解
洛谷 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 音乐会的等待 题解
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。