南邮 OJ 1036 自由堆叠的屋顶

来源:互联网 发布:样本数据的相关系数 编辑:程序博客网 时间:2024/05/01 15:54

自由堆叠的屋顶

时间限制(普通/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;}




0 0
原创粉丝点击