题目描述
诺诺表现、成绩双优,于是校长给她一笔money,让她去外地玩玩。由于本地没有飞机场,所以诺诺只能坐火车去咯。所以诺诺今天去火车站买票,却看到了N多人在火车站里啊,诺诺一阵头晕。机灵的她突然发现,有N个人在队伍里(和上文的N毫无关系- -||),人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的。
诺诺想计算出有多少对人可以互相看见,那么你能帮帮诺诺吗?
本题数据范围:
40%的测试数据:N≤10000;
80%的测试数据:N≤100000;
100%的测试数据:N≤500000。
输入格式
输入的第一行包含一个整数N (1≤N≤500 000), 表示队伍中共有N个人;
接下来的N行中,每行包含一个整数,表示人的高度,人的高度<10000。
输出格式
输出仅有一行,包含一个数S,表示队伍中共有S对人可以互相看见。
样例输入
样例输出
单调栈。
这道题考虑到特殊数据,但是发现自己将特殊数据答案算错了
5
5 5 3 5 5
8
开始一直算成9了,注意题目讲的是 他们是相邻或他们之间没有人比A或B高,
不过这道题需要考虑到相等的情况。
单调栈。
这道题考虑到特殊数据,但是发现自己将特殊数据答案算错了
5
5 5 3 5 5
8
开始一直算成9了,注意题目讲的是 他们是相邻或他们之间没有人比A或B高,
不过这道题需要考虑到相等的情况。
<span style="color:#000000;">#include <stdio.h>
#define LL long long
const int maxn = 500005;
int a[maxn], stack[maxn];
int main ( )
{
int n, top = -1;
LL ans = 0;
scanf ( "%d", &n );
for ( int i = 0; i < n; i ++ )
scanf ( "%d", &a[i] );
for ( int i = 0; i < n; i ++ )
{
if ( top < 0 || a[i] <= stack[top] )
{
int j = top;
while ( j >= 0 && a[i] == stack[j] )
//**注意stack[top]比a[i]大是不行的
{
ans ++;
j --;
}
if ( j >= 0 ) //遍历完就不需要加1,否则前面那个肯定是大于a[i]
ans ++;
stack[++ top] = a[i];
}
else
{
while ( top >= 0 && stack[top] < a[i] )
//将所有比a[i]小的数出栈,并统计个数
ans ++, top --;
int j = top;
while ( j >= 0 && stack[j] == a[i] )
//**考虑前面相等的情况,且不需要删除
ans ++, j --;
if ( j >= 0 ) //注意这里判断要是j
ans ++;
stack[++ top] = a[i];
}
//printf ( "**%d\n", ans );
}
printf ( "%lld", ans );
return 0;
}
/*
5
5 5 3 5 5
8
*/</span>