P1823 音乐会的等待

题目描述

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

这道题一开始自己推出来了如果后面有比他大的那么这个数是没用的,

然后乱搞了一下搞了25分。。。

看了一下题解发现一个非常好的思路

就是把相等和大于放到一个循环里判断,

一开始num==1保证有数据读入

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<stack>
 6 using namespace std;
 7 int read(int & n)
 8 {
 9     char c=‘-‘;int x=0;
10     while(c<‘0‘||c>‘9‘)c=getchar();
11     while(c>=‘0‘&&c<=‘9‘)
12     {
13         x=x*10+(c-48);
14         c=getchar();
15     }
16     n=x;
17 }
18 const int MAXN=500001;
19 stack<int>s;
20 int main()
21 {
22     int n,h,ans=0,flag=0;
23     read(n);
24     for(int i=1;i<=n;i++)
25     {
26         flag=0;
27         read(h);
28         if(i==1)
29         {
30             s.push(h);
31             continue;
32         }
33         if(h>s.top())
34         {
35             ans++;
36             s.pop();
37             while(s.size()>0&&h>s.top())
38             {
39                 ans++;
40                 s.pop();
41                 flag=1;
42             }
43             if(s.size()!=0&&h<s.top())
44             ans++;
45             s.push(h);
46         }
47         else if(h==s.top())
48         {
49             ans=ans+s.size();
50             s.push(h);
51         }
52         else
53         {
54             ans++;
55             s.push(h);
56         }
57     }
58     printf("%d",ans);
59 }

乱搞25分

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<stack>
 6 using namespace std;
 7 int read(int & n)
 8 {
 9     char c=‘-‘;int x=0;
10     while(c<‘0‘||c>‘9‘)c=getchar();
11     while(c>=‘0‘&&c<=‘9‘)
12     {
13         x=x*10+(c-48);
14         c=getchar();
15     }
16     n=x;
17 }
18 const int MAXN=500001;
19 stack<int>s;
20 int main()
21 {
22     int n,h,ans=0,flag=0;
23     read(n);
24     for(int i=1;i<=n;i++)
25     {
26         int num=1;
27         read(h);
28         while(s.size()!=0&&h>=s.top())
29         {
30
31             if(h==s.top())
32             num++;
33             ans++;
34             s.pop();
35         }
36         if(s.size()!=0)
37         ans++;
38         while(num--)
39         s.push(h);
40     }
41     printf("%d",ans);
42 }
时间: 2024-10-22 07:36:07

P1823 音乐会的等待的相关文章

洛谷P1823 音乐会的等待 单调栈

洛谷P1823 音乐会的等待 单调栈 维护一个上升的单调栈 用以记录有当前这个数向后能看到几个数 但是每次加入一个数 时 他能看到的 是 单调栈中所有比他小的 和跟他一样的数 比他小的下次就没有用了,所以直接退栈 但是 相同的数到后面还是可能会有贡献的,所以贡献算完以后又要进栈 最后如果栈中还有元素,那么栈顶一定能看到自身,所以+1 1 #include <bits/stdc++.h> 2 #define For(i,j,k) for(int i=j;i<=k;i++) 3 #defin

洛谷——P1823 音乐会的等待

https://www.luogu.org/problem/show?pid=1823 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. 写一个程序计算出有多少对人可以互相看见. 输入输出格式 输入格式: 输入的第一行包含一个整数N (1 ≤ N ≤ 500 000), 表示队伍中共有N个人. 接下来的N行中,每行包含一个整数,表示人的高度,以毫微

洛谷 P1823 音乐会的等待

题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. 写一个程序计算出有多少对人可以互相看见. 输入输出格式 输入格式: 输入的第一行包含一个整数N (1 ≤ N ≤ 500 000), 表示队伍中共有N个人. 接下来的N行中,每行包含一个整数,表示人的高度,以毫微米(等于10的-9次方米)为单位,每个人的调度都小于2^31毫微米.这些高度分别表示队伍

洛谷 P1823 音乐会的等待 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1823 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. 写一个程序计算出有多少对人可以互相看见. 输入输出格式 输入格式: 输入的第一行包含一个整数N (1 ≤ N ≤ 500 000),

音乐会的等待-单调栈

关于本题,这里只是基础的写法,完美的避开了特殊情况,另一篇博文会详细讲解特殊情况 [COI2007] Patrik 音乐会的等待 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. 写一个程序计算出有多少对人可以互相看见. 输入输出格式 输入格式: 输入的第一行包含一个整数N (1 ≤ N ≤ 500 000), 表示队伍中共有N个人. 接下来的N行

音乐会的等待-单调栈(进阶版)

这道题的基础做法在上一篇博文中已经提到了,详情请见:https://www.cnblogs.com/yufenglin/p/10306366.html 而在课上有人提到了一种简便做法(错的,但可以改对),先来回顾一下题目: 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. 写一个程序计算出有多少对人可以互相看见. 输入输出格式 输入格式: 输入的第

【刷题】【单调栈】音乐会的等待

N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. 写一个程序计算出有多少对人可以互相看见. 重点: (1)看题要仔细 (2)不开long long 见祖宗 解法神奇 #include<cstdio> #include<cstdlib> #include<stack> #define ll long long using namesp

音乐会的等待-题解

查看原题请戳这里 感觉这道题用单调栈做这一点还是很容易看出来的. 然后我们就会发现其实现在问题变得非常的简单. 每次读入一个数,就找到第一个比它小的数并进行替换,然后将前面的数全部删掉就可以了,处理每一个数的时候都要更新一下答案. 附一下代码: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long n,top; long long Ans; int a[

寒假2周打卡

2019-02-07 lyd字符串hash 学了Manacher算法 2019-02-08 今天去了趟姥姥家 晚上学了一下kmp算法 2019-02-09 继续学kmp+exkmp 2019-02-10 今天去喝喜酒,今天真的好烦,我不会喝酒,他们都在喝,所以对我有种讨厌的感觉,在酒桌上的感觉就要死了,下次不会再喝这种喜酒. 今天做的题有点少 题:数据分配:优先队列 2019-02-11 做玉蟾宫那题时,发现了还有悬线法,不过看过以后不能完全理解 今日打卡(悬线法)  (洛谷) 1.p1387