首页 > 代码库 > HDU 1255 覆盖的面积(线段树扫描线)
HDU 1255 覆盖的面积(线段树扫描线)
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
线段树扫描线:
跟上一题类似,不过既然求重叠面积,要求覆盖次数要两次以上。
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<bitset> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) typedef long long LL; typedef pair<int,int>pil; const int maxn=2000+100; struct node{ int l,r; int c;//记录重叠次数 double lf,rf; double len1,len2;//len1,len2分别为覆盖一次,两次的长度 }t[maxn<<2]; struct Line{ double x,y1,y2; int f; }line[maxn]; double y[maxn]; int cas,n; int cmp(Line l1,Line l2) { return l1.x<l2.x; } void build(int l,int r,int rs) { t[rs].l=l;t[rs].r=r; t[rs].c=0; t[rs].len1=t[rs].len2=0; t[rs].lf=y[l]; t[rs].rf=y[r]; if(l+1==r) return ; int mid=(l+r)>>1; build(l,mid,rs<<1); build(mid,r,rs<<1|1); } void pushup(int rs) { if(t[rs].c>=2) { t[rs].len1=t[rs].len2=t[rs].rf-t[rs].lf; return ; } else if(t[rs].c==1) { t[rs].len1=t[rs].rf-t[rs].lf; if(t[rs].l+1==t[rs].r) t[rs].len2=0; else t[rs].len2=t[rs<<1].len1+t[rs<<1|1].len1; } else { if(t[rs].l+1==t[rs].r) t[rs].len1=t[rs].len2=0; else { t[rs].len1=t[rs<<1].len1+t[rs<<1|1].len1; t[rs].len2=t[rs<<1].len2+t[rs<<1|1].len2; } } } void update(int rs,Line e) { if(e.y1==t[rs].lf&&e.y2==t[rs].rf) { t[rs].c+=e.f; pushup(rs); return ; } if(e.y2<=t[rs<<1].rf) update(rs<<1,e); else if(e.y1>=t[rs<<1|1].lf) update(rs<<1|1,e); else { Line temp=e; temp.y2=t[rs<<1].rf; update(rs<<1,temp); temp=e; temp.y1=t[rs<<1|1].lf; update(rs<<1|1,temp); } pushup(rs); } int main() { double x1,y1,x2,y2; scanf("%d",&cas); while(cas--) { scanf("%d",&n); int tt=1; REP(i,n) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[tt].x=x1; line[tt].y1=y1; line[tt].y2=y2; line[tt].f=1; y[tt]=y1; tt++; line[tt].x=x2; line[tt].y1=y1; line[tt].y2=y2; line[tt].f=-1; y[tt]=y2; tt++; } sort(line+1,line+tt,cmp); sort(y+1,y+tt); build(1,tt-1,1); update(1,line[1]); double ans=0; for(int i=2;i<tt;i++) { ans+=t[1].len2*(line[i].x-line[i-1].x); update(1,line[i]); } printf("%.2f\n",ans); } return 0; }
HDU 1255 覆盖的面积(线段树扫描线)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。