【NOIP普及组模拟赛3】投影(skyline)

  1. 投影(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)描述照片中建筑物高度发生变化的位置,你的任务是计算出最少需要多少个建筑才能形成该照片。
如下图:
【NOIP普及组模拟赛3】投影(skyline)_第1张图片
输入
第一行: 两个空格隔开的整数N,W;
第2到N+1行:两个空格隔开的整数x和y,表示发生改变的点的坐标。输入中x是严格递增的而且第1个x一定是1。

输出
输出最少需要多少建筑才能形成该照片。

思路:用这个数据盖最小数量的房子,假如每一个高度变化就等于射出一根线,并且把比变化高度高的线去掉。

那么,如果有一根等于它高度的线,那就代表这高度与以前重叠,ans不变;如果没有,ans++,加入一根线。

实现也很简单。

要了解一下set红黑树,在STL模板有讲。

栗子

#include
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
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;
}

没错就这点代码就能解决这题。

写博不易,请发现问题的大佬提出。

代码保证正确,请留赞再走。

你可能感兴趣的:(题解)