博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

洛谷P1823 音乐会的等待

To 洛谷.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

代码:

栈模拟。

 1 #include<cstdio>
 2 using namespace std;
 3 
 4 int n,Ans;
 5 struct Stack
 6 {
 7     int tp,sz[500005];
 8     Stack()
 9     {
10         tp=0;
11     }
12     void Del()
13     {
14         --tp;
15     }
16     int Get()
17     {
18         return sz[tp];
19     }
20     bool Empty()
21     {
22         return tp==0;
23     }
24     void Insert(int x)
25     {
26         sz[++tp]=x;
27     }
28 }s;
29 
30 void read(int &now)
31 {
32     now=0;char c=getchar();
33     while(c<'0'||c>'9')c=getchar();
34     while(c>='0'&&c<='9')now=now*10+c-'0',c=getchar();
35 }
36 
37 int main()
38 {
39     read(n);
40     int a;
41     while(n--)
42     {
43         read(a);int t=1;
44         while(a>=s.Get() && !s.Empty())
45         {//当当前高度比栈顶元素大时,栈中元素要一直弹出直到栈顶大于等于当前高度 
46         //(比当前小的都看不见后面的了) 
47         //每次弹出Ans都++(比当前矮的可以看见当前元素,但不能看见以后的元素 so弹出) 
48         //这里将所有等于当前元素的也一起弹出了,并记录弹出个数 
49             if(s.Get()==a) ++t;
50             s.Del(),++Ans;
51         }
52         if(!s.Empty())//此时栈中还有 那一定是大于当前高度的,他们可以互相看见 
53           ++Ans;
54         while(t--)//将原先等于当前的重新入栈 因为t初始=1,所以当前的也会算在内 入栈 
55           s.Insert(a);
56     }
57     
58     printf("%d",Ans);    
59     return 0;
60 }
posted @ 2017-05-21 13:49  SovietPower  阅读(144)  评论(0编辑  收藏  举报