题目描述
N个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的。
写一个程序计算出有多少对人可以互相看见。
输入输出格式
输入格式:
输入的第一行包含一个整数N (1 ≤ N ≤ 500 000), 表示队伍中共有N个人。
接下来的N行中,每行包含一个整数,表示人的高度,以毫微米(等于10的-9次方米)为单位,每个人的调度都小于2^31毫微米。这些高度分别表示队伍中人的身高。
输出格式:
输出仅有一行,包含一个数S,表示队伍中共有S对人可以互相看见。
输入输出样例
啥也不会,一上来就写的暴力。果然是太弱了,加油啊。
正解:
单调栈,维护一个单调栈,s[top]<=s[top-1]......
如果当前元素>=s[top],就把当前元素出栈,说明这是当前元素可以看见的,
同时更新答案。
如果到当前元素<s[top] && top>=1 时,就说明找到了他能看到的最远的人的最高距离,更新答案。
然后把当前元素以及重复的入栈。
详见代码
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<vector> 6 #include<map> 7 #include<queue> 8 #define ll long long 9 #define inf 2147483600 10 #define DB double 11 #define eps 1e-6 12 using namespace std; 13 const int N=500010; 14 int n,h,s[N],ans,top,k; 15 int main() 16 { 17 scanf("%d",&n); 18 for(int i=1;i<=n;++i) 19 { 20 scanf("%d",&h);k=1; 21 while(top>=1 && h>=s[top]) 22 { 23 if(s[top]==h) k++; 24 top--,ans++; 25 } 26 if(top) ans++; 27 while(k--) s[++top]=h; 28 } 29 printf("%d",ans); 30 return 0; 31 }
人生真的是付出多少就收获多少,那么,就然我从现在开始努力耕耘吧。
不怕晚,就怕不努力。