zoukankan      html  css  js  c++  java
  • EOJ 3213 向右看齐

    题目描述

    N 头奶牛被紧急动员起来了,它们排成了一条长列。从左向右看,排在第 i 个位置的奶牛身高为 Hi。约翰一声令下,所有奶牛向右看齐。假设每头奶牛只能看到比自己高的牛。请问它们各自看到的最近的一头奶牛分别是谁呢?
    Input

    第一行:单个整数 N,1≤N≤106

    第二行到 N+1 行:第 i+1 行有一个整数 Hi,1≤Hi≤106
    Output

    第一行到第 N 行:第 i 行有一个整数 Ci,表示第 i 头奶牛向右看到的最近的一头奶牛编号,如果看不到任何奶牛,Ci 为 0。


    一开始用朴素的循环遍历算法,如果单调递减,复杂度是O(n2),显然是不可行的。

    听同学讲解后才知道是单调栈,具体见转载的相关博客。

    C语言实现

     1 #include  <stdio.h>
     2 #define N 100010
     3 int main()
     4 {
     5     int n;scanf("%d",&n);
     6     int h[N],ans[N];
     7     for(int i=1; i<=n; i++)  scanf("%d",&h[i]);
     8     ans[n]=0;
     9     for(int i=n-1; i>=1; i--)
    10     {
    11         if(h[i]<h[i+1]) ans[i]=i+1;
    12         else if(h[i]==h[i+1])ans[i]=ans[i+1];
    13         else
    14         {
    15             int j=i;
    16             for(;h[i]>=h[ans[j+1]];j++)
    17                 if(ans[j+1]==0) break;
    18             ans[i]=ans[j+1];
    19         }
    20     }
    21     for(int i=1; i<=n; i++)
    22         printf("%d
    ",ans[i]);
    23 
    24 }是

    细读就可以理解含义,最后一头奶牛向右没有,编号是0,依次向前遍历,对于奶牛i,如果高度低于后一头i+1,那么编号i+1,如果高度相同,后一头能看到的最近的奶牛也必然是i能看到的奶牛,故编号为ans[i+1],当高度高于前一头奶牛,就需要向后遍历直到后面的最高的奶牛。显然,这不是单调栈。(逃

    并且在第三种情况下,时间复杂度略高。


    以下是单调栈的写法,实现语言C++

     1 #include <iostream>
     2 #include <stack>
     3 #define N 1000001
     4 using namespace std;
     5 int main()
     6 {
     7     stack<pair<int,int> > s;
     8     int T,tmp;cin>>T;
     9     int ans[N];
    10     for(int m=1;m<=T;m++){
    11         cin>>tmp;
    12         if(!s.empty())
    13             while(!s.empty()&&s.top().first<tmp){
    14                 ans[s.top().second]=m;
    15                 s.pop();
    16             }
    17         s.push(make_pair(tmp,m));
    18     }
    19     while(!s.empty()){
    20         ans[s.top().second]=0;
    21         s.pop();
    22     }
    23     for(int i=1;i<=T;i++) cout<< ans[i] <<endl;
    24     return 0;
    25 }

    还用一种更快(一点点)的是额外开一个数组记录读取的数字,stack只需要记录下标,或者反过来,总之原理是一样的。

  • 相关阅读:
    HDU 5585 Numbers
    HDU 3308 LCIS
    POJ 2991 Crane
    POJ 1436 Horizontally Visible Segments
    POJ 3667 Hotel
    HaiHongOJ 1003 God Wang
    【SDOI 2008】 递归数列
    5月19日省中提高组题解
    【HDU 1588】 Gauss Fibonacci
    【POJ 3233】Matrix Power Series
  • 原文地址:https://www.cnblogs.com/Jiiiin/p/8593004.html
Copyright © 2011-2022 走看看