单调栈(应用)

不多说,直接上题:

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

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

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

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

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

这是我们就要把目标指向各个影子的高度,高度的关系无万户,高与低,我们就从这两个方面分析,设有两个影子的高度分别为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

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

posted @ 2019-03-26 12:56  逆天峰  阅读(205)  评论(0编辑  收藏  举报
作者:逆天峰
出处:https://www.cnblogs.com/gcfer//