• 瞭望塔——单调栈


    题目

    链接

    在蒜国的海岸线上有一排由西向东的瞭望塔,这些瞭望塔由于建造的地面高度不同,所有瞭望塔的高度也是不能不一样的。

    这个时候蒜国国王来问蒜头君,每个瞭望塔向东能看到几个瞭望塔?这里需要注意在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 ? '
    ': ' ');
    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 ? '
    ': ' ');
    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 }
    View Code
  • 相关阅读:
    mysql的用户权限设置
    Jmeter——BeanShell PreProcessor的用法
    zhlan--巧用Python中的正则表达式符号
    【直播预告】云栖直播:阿里热修复产品HotFix2.0升级详解
    双十一 手淘技术用了这几招
    用户说体验 | 关于阿里百川HotFix你需要了解的一些细节
    阿里百川码力APP监控 来了!
    淘宝直播技术分享:如何打造体验优秀的“直播+”产品?
    云栖大会上宣布即将开源的手淘Atlas什么来头?
    推进"五通一平":手淘技术"三大容器 五大方案"首次整体亮相 百川开放升级
  • 原文地址:https://www.cnblogs.com/lfri/p/11131991.html
Copyright © 2020-2023  润新知