• 单调栈(应用)


    不多说,直接上题:

    这个题目猛的一看毫无思路,想用爆搜...

    鄙人同样,这个题曾经卡了我很多月...

    看这个题的输入格式,明显和搜索没什么关系。

    再看看样例仔细思考,发现各个影子的高度与最终答案有关.

    再看样例,第一张图很明显的告诉我们建筑数与相邻近影子的高度有关,再看第二张与第三张,就没有一点头绪了,样例给我们的提示就这么多了,只能自己思考了。

    这是我们就要把目标指向各个影子的高度,高度的关系无万户,高与低,我们就从这两个方面分析,设有两个影子的高度分别为i,j;如果i比j大,很明显要将i单独拿出来,当做一个建筑(因为i比j高出的那一段没法弥补,只能将i单独拿出来),如果i比j小,那i就可以先不管,因为j比i高,i的那一部分完全可以等到处理一个比i更小的一个影子时再处理,如果i和j相等则当成一个影子即可,这是就会发现每个影子只与在他右方最近的且比它低的影子有关,符合单调栈的性质;

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=51000;
    int stak[maxn],N,W,a[maxn],o,top,ans;
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-') ff=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*ff;
    }
    inline void put(int x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) put(x/10);
        putchar(x%10+'0');
    }
    int main()
    {
        freopen("1.in","r",stdin);
        N=read();W=read();
        int x=0;
        while(cin>>x)
        {
            int y=read();
            a[++o]=y;
        }
        //for(int i=1;i<=o;i++) cout<<a[i]<<endl;
        for(int i=1;i<=o;i++)
        {
            while(top>=1&&a[i]<=stak[top]) if(a[i]!=stak[top--]) ans++;
            stak[++top]=a[i];
        }
        while(top)
        {
            if(stak[top--]) ans++;
        }
        cout<<ans<<endl;
    }
    View Code

    这个题告诉我们一般样例都是以正解的形式给出的,没有思路时可以与样例相结合.

  • 相关阅读:
    HDU
    HDU
    HDU
    HDU
    HDU
    HDU
    HDU
    HDU
    HDU
    HDU
  • 原文地址:https://www.cnblogs.com/gcfer/p/10599438.html
Copyright © 2020-2023  润新知