南邮 OJ 1036 自由堆叠的屋顶

自由堆叠的屋顶

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 100            测试通过 : 38 

比赛描述

sed 同学最近突发奇想,认为伟大的建筑物的屋顶应该是“自由堆叠”出来的,他的设计方案是:将各种颜色的长方形建筑板材堆叠在一起,并保证各个板材长边、宽边均相互平行或在一条直线上,板材之间的重叠部分用连接装置固定在一起。

你的任务是计算这个“自由堆叠的屋顶”所覆盖的面积。sed 将会在屋顶平面上建立一个二维坐标系,提供给你每个长方形建筑板材左上角、右下角的坐标。为简化计算,这里忽略板材的厚度,假设它们都在同一个平面上。



输入

输入数据包含多组测试案例。

每组测试案例由N(0≤N≤100)开头,后续N行每行包含4个实数x1;y1;x2;y2 (0 <= x1 < x2 <= 100000建筑单位;0 <= y1 < y2 <= 100000建筑单位)。

(x1; y1) 、 (x2;y2)分别是长方形建筑板材左上角、右下角的坐标。

单独一个行输入0表示输入结束,无需处理。

输出

对于每个测试用例,输出以下信息: 第1行形如“Build #k”,这里k是测试用例序号(以1开始),第二行形如“Total area: a”,a是总覆盖面积,保留两位小数。

样例输入

2
10 10 20 20
15 15 25 25.5
1
10 10 20 20
0

样例输出

Build #1
Total explored area: 180.00
Build #2
Total explored area: 100.00

题目来源

南京邮电大学计算机学院首届ACM程序设计大赛(2009)


#include <iostream>
#include <iomanip>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

struct seg{				//水平线段
	double x1;
	double x2;
	double y;
	bool upIsArea;		//线段上面是面积	
};
bool comp(seg seg1,seg seg2){
	return seg1.y < seg2.y;
}
int main(void){
	int N=0,buildNo=0,i=0,j=0,count=0;
	double x1=0,y1=0,x2=0,y2=0,area,bottomY=0;
	bool bottomFlag=1;				//框的底部
	seg aSeg;
	vector<seg> segs;
	set<double> xs;					//set插入不重复
	set<double>::iterator sIt;
	while(cin>>N && N){
		++buildNo;
		segs.clear();
		xs.clear();
		area = 0;
		for(i=0;i<N;++i){
			cin>>x1>>y1>>x2>>y2;
			aSeg.x1 = x1;
			aSeg.x2 = x2;
			aSeg.y = y1;
			aSeg.upIsArea = 1;					//上面是面积
			segs.push_back(aSeg);
			aSeg.y = y2;
			aSeg.upIsArea = 0;					//下面是面积
			segs.push_back(aSeg);
			xs.insert(x1);
			xs.insert(x2);
		}
		sort(segs.begin(),segs.end(),comp);
		sIt = xs.begin();
		for(i=0;i<int(xs.size())-1;++i){		//用x坐标分段
			x1 = *sIt;
			x2 = *(++sIt);
			count = 0;
			bottomFlag = 1;	
			for(j=0;j<int(segs.size());++j){
				if(segs[j].x1<=x1 && segs[j].x2>=x2){	//段内的水平线
					if(bottomFlag){
						bottomY = segs[j].y;
						bottomFlag = 0;
					}
					if(segs[j].upIsArea){
						count++;
					}else{
						count--;
					}
					if(count == 0){
						area += (x2-x1)*(segs[j].y-bottomY);
						bottomFlag = 1;
					}
				}
			}
		}
		cout<<"Build #"<<buildNo<<endl;
		cout<<"Total explored area: "<<fixed<<setprecision(2)<<area<<endl;
	}
	return 0;
}




你可能感兴趣的:(ACM,南邮OJ,自由堆叠的屋顶)