覆盖的面积
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5019 Accepted Submission(s): 2515
Problem Description
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
Input
输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.
注意:本题的输入数据较多,推荐使用scanf读入数据.
注意:本题的输入数据较多,推荐使用scanf读入数据.
Output
对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.
Sample Input
2
5
1 1 4 2
1 3 3 7
2 1.5 5 4.5
3.5 1.25 7.5 4
6 3 10 7
3
0 0 1 1
1 0 2 1
2 0 3 1
Sample Output
7.63
0.00
Author
Ignatius.L & weigang Lee
呵呵,这题是在线段树求矩形面积并的基础上再进一步。segment_tree中的len表示覆盖一遍的长度,nlen表示覆盖多遍的长度。这题的重点在于写if语句判断三个要点:1)此区间已经覆盖2遍及以上;2)此区间被覆盖一次,区间是还是不是叶子节点,若不是,则有没有被覆盖两次取决于它子节点len值;3)此区间没被覆盖。
Problem :
1255 ( 覆盖的面积 ) Judge Status :
Accepted
RunId : 17414345 Language : G++ Author : ksq2013
Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta
RunId : 17414345 Language : G++ Author : ksq2013
Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; double yy[2100]; struct Line{ int f; double x,y1,y2; bool operator<(const Line h)const{ return x<h.x; } }line[2100];//index:m; struct Seg{ int f; double len,nlen; }tr[10100]; void build(int s,int t,int k) { tr[k].f=tr[k].len=tr[k].nlen=0; if(s+1==t)return; int m=(s+t)>>1; build(s,m,k<<1); build(m,t,k<<1|1); } int bin(double x,int l,int r) { while(l<=r){ int mid=(l+r)>>1; if(yy[mid]==x)return mid; if(yy[mid]<x)l=mid+1; else r=mid-1; }return l; } void pushup(int s,int t,int k) { if(tr[k].f>1)tr[k].nlen=tr[k].len=yy[t]-yy[s]; else{ if(tr[k].f==1){ tr[k].len=yy[t]-yy[s]; if(s+1==t)tr[k].nlen=0; else tr[k].nlen=tr[k<<1].len+tr[k<<1|1].len; } else{ if(s+1==t)tr[k].nlen=tr[k].len=0; else{ tr[k].len=tr[k<<1].len+tr[k<<1|1].len; tr[k].nlen=tr[k<<1].nlen+tr[k<<1|1].nlen; } } } } void update(int s,int t,int k,int l,int r,int f) { if(l<=s&&t<=r){ tr[k].f+=f; pushup(s,t,k); return; }int m=(s+t)>>1; if(l<m)update(s,m,k<<1,l,r,f); if(m<r)update(m,t,k<<1|1,l,r,f); pushup(s,t,k); } int main() { int T,n; double x1,y1,x2,y2; scanf("%d",&T); for(;T;T--){ scanf("%d",&n); int m=0; for(int i=1;i<=n;i++){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); yy[++m]=y1; line[m].f=1;//initial number:0;first variable:f; line[m].x=x1; line[m].y1=y1; line[m].y2=y2; yy[++m]=y2; line[m].f=-1; line[m].x=x2; line[m].y1=y1; line[m].y2=y2; } sort(1+yy,1+m+yy);//data input; sort(1+line,1+m+line); int k=1; for(int i=2;i<=m;i++) if(yy[i-1]!=yy[i])yy[++k]=yy[i];//end; double ans=0; build(1,k,1);//build a segment_tree; for(int i=1;i<=m;i++){ update(1,k,1,bin(line[i].y1,1,k),bin(line[i].y2,1,k),line[i].f);//updating segments by binary search; ans+=tr[1].nlen*(line[i+1].x-line[i].x); } printf("%.2lf ",ans);//output the ans; } return 0; }