瞭望塔——单调栈
Posted lfri
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了瞭望塔——单调栈相关的知识,希望对你有一定的参考价值。
题目
在蒜国的海岸线上有一排由西向东的瞭望塔,这些瞭望塔由于建造的地面高度不同,所有瞭望塔的高度也是不能不一样的。
这个时候蒜国国王来问蒜头君,每个瞭望塔向东能看到几个瞭望塔?这里需要注意在A塔东边有B塔,B塔的高度高于或等于A塔的高度,那么B塔后面的塔都看不到。
解决方案
由题意知,求左边第一个大于或等于自身的数。
由单调栈的知识,只需维护一个严格单调递减的栈,即当前元素大于或等于栈顶元素时一直出栈,当前元素小于栈顶元素将当前元素直接进栈。每当一个元素弹出的时候,那么被弹出的元素,最远可以看到的塔就是即将插入的塔,然后两个位置做个差就可以了。
最后栈里面剩余的元素都是可以看到第 $n$个塔的(可假设$n+1$有一个非常高的塔)
C++版
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 const int maxn = 1000000 + 10; 6 int n, a[maxn]; 7 8 stack<int>s; 9 int index[maxn]; 10 11 void solve() 12 13 14 for(int i = 1;i <= n;i++) 15 16 while(!s.empty() && a[i] >= a[s.top()]) 17 18 index[s.top()] = i - s.top(); 19 s.pop(); 20 21 s.push(i); 22 23 24 int tmp = 0; 25 while(!s.empty()) 26 27 index[s.top()] = tmp++; 28 s.pop(); 29 30 for(int i = 1;i <= n;i++) printf("%d%c", index[i], i == n ? ‘\n‘: ‘ ‘); 31 32 33 int main() 34 35 scanf("%d", &n); 36 for(int i = 1; i <= n;i++) scanf("%d", &a[i]); 37 solve(); 38
C版
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<stdbool.h> 4 #define maxsize 1000010 5 #define maxn 1000010 6 7 int data[maxsize]; 8 int top; 9 10 typedef long long ll; 11 int n, a[maxn]; 12 int index[maxn]; 13 14 void InitStack() 15 16 top = -1; 17 18 19 bool StackEmpty() 20 21 return top == -1; 22 23 24 void Push(int e) 25 26 top++; 27 data[top] = e; 28 29 30 void Pop() 31 32 top--; 33 34 35 int GetTop() 36 37 return data[top]; 38 39 40 void solve() 41 42 for(int i = 1;i <= n;i++) 43 44 while(!StackEmpty() && a[i] >= a[GetTop()]) 45 46 index[GetTop()] = i - GetTop(); 47 Pop(); 48 49 Push(i); 50 51 while(!StackEmpty()) 52 53 index[GetTop()] = n - GetTop(); 54 Pop(); 55 56 for(int i = 1;i <= n;i++) printf("%d%c", index[i], i == n ? ‘\n‘: ‘ ‘); 57 58 59 int main() 60 61 scanf("%d", &n); 62 for(int i = 1; i <= n;i++) scanf("%d", &a[i]); 63 solve(); 64
以上是关于瞭望塔——单调栈的主要内容,如果未能解决你的问题,请参考以下文章