- 投影(skyline)
(File IO): input:skyline.in output:skyline.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet
题目描述
一天你对着眼前的景物拍了一张照,这个相机很特别,有建筑物的地方显示“X”,没有建筑物的地方显示为“.”,假设每个建筑都是块状的,照片长W(1<=W<=1,000,000),用N(1<=N<=50,000)对平面坐标(x,y)( 1 <= x <= W, 0 <= y <= 500,000)描述照片中建筑物高度发生变化的位置,你的任务是计算出最少需要多少个建筑才能形成该照片。
如下图:
输入
第一行: 两个空格隔开的整数N,W;
第2到N+1行:两个空格隔开的整数x和y,表示发生改变的点的坐标。输入中x是严格递增的而且第1个x一定是1。
输出
输出最少需要多少建筑才能形成该照片。
思路:用这个数据盖最小数量的房子,假如每一个高度变化就等于射出一根线,并且把比变化高度高的线去掉。
那么,如果有一根等于它高度的线,那就代表这高度与以前重叠,ans不变;如果没有,ans++,加入一根线。
实现也很简单。
要了解一下set红黑树,在STL模板有讲。
栗子:
#include<bits/stdc++.h>
using namespace std;
multiset<int>st; //定义int型的set;
multiset<int>::iterator it; //定义set的送代器;
定义了一个int型的st红黑树队列。
有如下操作:
st.clear(); //清零
st.insert(x); //加入x
*(--st.end()); //队列最大值
st.erase(--st.end()); //清除队列最大值
了解了这些就可一打代码了:
#include<bits/stdc++.h>
using namespace std;
int n,w,ans,x,y,ma;
multiset<int>st;
multiset<int>::iterator it;
int main()
{
// freopen("skyline.in","r",stdin);
// freopen("skyline.out","w",stdout);
st.clear();
st.insert(0);
scanf("%d%d",&n,&w);
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
ma=0;
while(*(--st.end())>y){
st.erase(--st.end());
}
if(y>*(--st.end())){
ans++;
st.insert(y);
}
}
cout<<ans;
fclose(stdin);
fclose(stdout);
return 0;
}
没错就这点代码就能解决这题。
写博不易,请发现问题的大佬提出。
代码保证正确,请留赞再走。