题目描述
n 个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。
队列中任意两个人 a和 b,如果他们是相邻或他们之间没有人比 a 或 b 高,那么他们是可以互相看得见的。
写一个程序计算出有多少对人可以互相看见。
输入格式
输入的第一行包含一个整数 n,表示队伍中共有 n 个人。
接下来的 nn 行中,每行包含一个整数,表示人的高度,以毫微米(等于 10^{-9}10−9 米)为单位,这些高度分别表示队伍中人的身高。
输出格式
输出仅有一行,包含一个数 s,表示队伍中共有 s 对人可以互相看见。
输入输出样例
输入 #1
7 2 4 1 2 2 5 1
输出 #1
10
说明/提示
数据规模与约定
对于全部的测试点,保证 1\le1≤ 每个人的高度 < 2^{31}<231,1 \le n \le 5\times 10^51≤n≤5×105。
答题思路
边输入边判断,用单调栈的思路,当当前数被压入栈时,进行第一次判断,如果当前数大于栈顶数,则将栈顶数弹出并将对数加加,但如果栈顶的第一个数与栈顶下一个数一样,就会出现问题,通过分析样例就可以知道,那么这时就可以把它设为结构体,来判断。
压入栈时也要判断,如果栈内部不为空,对数就要加加,因为压入的数一定可以与此时栈顶(未压入当前数时)相互看见,但如果栈内部为空就不行了。
那么我们现在就只需把上面的文字转换为代码就行了
AC代码
#include <bits/stdc++.h>
using namespace std;
long long n, cnt = 0;struct pl {
long long h, c = 1;
} o[500050];stack<pl>q;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> o[i].h;
while (!q.empty() && o[i].h >= q.top(). h) {
cnt += q.top().c;
//统计高度h的连续次数
if (o[i].h == q.top().h)
o[i].c += q.top().c;
q.pop();
}
if (!q.empty())
cnt++;
q.push(o[i]);
}
cout << cnt;
return 0;
}