1. 程式人生 > >洛谷 P1823 音樂會的等待

洛谷 P1823 音樂會的等待

升序 gis 不同 人的 san ack pla log etc

題目描述

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

首先有基礎的n-1對 再用單調棧維護 一個不升序列 彈出一個數 ans就加1

然而只有0分

正解也是棧 ,只是不同的處理

因此,對於新加入單調棧的一個元素,我們分三種情況討論:

1、新元素num比stack[top]小:直接加入棧,只能與棧首配對,ans加一

2、新元素num與stack[top]相等:可以與棧首所有相等元素配對,ans加棧中與棧首元素相等的數的個數,同時ans還應再加一,因為num還能與棧中第一個比Num大的數配對

3、新元素num比stack[top]大:不斷彈出元素,每彈一個ans加一,一直彈到num <= stack[top],同2理進行判斷即可。

技術分享
 1 #include <ctype.h>
 2 #include <cstdio>
 3 
 4 const int MAXN=500010;
 5 
 6 int n,top,ans,x;
 7 
 8 int stack[MAXN];
 9 
10 inline void read(int&x) {
11     register char c=getchar();
12     for
(x=0;!isdigit(c);c=getchar()); 13 for(;isdigit(c);x=x*10+c-48,c=getchar()); 14 } 15 16 int hh() { 17 read(n); 18 for(int i=1;i<=n;++i) { 19 read(x); 20 int t=0; 21 while(top&&stack[top]<x) --top,++ans; 22 while(x==stack[top]&&top) --top,++ans,++t; 23 if(top) ++ans; 24 top+=t; 25 stack[++top]=x; 26 } 27 printf("%d\n",ans); 28 return 0; 29 } 30 31 int sb=hh(); 32 int main() {;}
代碼

洛谷 P1823 音樂會的等待