不多说,直接上题:
这个题目猛的一看毫无思路,想用爆搜...
鄙人同样,这个题曾经卡了我很多月...
看这个题的输入格式,明显和搜索没什么关系。
再看看样例仔细思考,发现各个影子的高度与最终答案有关.
再看样例,第一张图很明显的告诉我们建筑数与相邻近影子的高度有关,再看第二张与第三张,就没有一点头绪了,样例给我们的提示就这么多了,只能自己思考了。
这是我们就要把目标指向各个影子的高度,高度的关系无万户,高与低,我们就从这两个方面分析,设有两个影子的高度分别为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; }
这个题告诉我们一般样例都是以正解的形式给出的,没有思路时可以与样例相结合.