您的位置:首页 > 其它

HDU - 1255 - 覆盖的面积(线段树)

2017-08-30 13:59 381 查看


覆盖的面积

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6172    Accepted Submission(s): 3113


Problem Description

给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.



 

Input

输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.

注意:本题的输入数据较多,推荐使用scanf读入数据.

 

Output

对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.

 

Sample Input


251 1 4 21 3 3 72 1.5 5 4.53.5 1.25 7.5 46 3 10 730 0 1 11 0 2 12 0 3 1

 

Sample Output


7.630.00

 

题意:

求矩形重合的面积之和。

扫描线,离散化

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define lx x<<1
#define rx x<<1|1
#define mid ((L+R)>>1)
const int N = 2e3 + 10;
const double eps = 1e-6;
int T,n,I,cover[N<<2];
double x1,x2,y1,y2,Rank
,sum[N<<2];
struct node{
double x,y1,y2;
int in;
node(double a,double b,double c,int d) {x = a; y1 = b; y2 = c; in = d;}
node(){}
}p
;
bool cmp(node a,node b){return a.x<b.x;}
void setRank(){
I = 1; sort(Rank+1,Rank+1+n*2);
for(int i=2;i<=n*2;i++) if(Rank[i]!=Rank[i-1]) Rank[++I] = Rank[i];
}
int getRank(double val) {return lower_bound(Rank+1, Rank+1+I, val) - Rank;}
void Cover(int x,int val,int l,int r,int L,int R){
if(L==R){
cover[x] += val;
sum[x] = cover[x] > 1 ? Rank[R+1] - Rank[L] : 0;
return;
}
if(l<=mid) Cover(lx, val, l, r, L, mid);
if(mid<r) Cover(rx, val, l, r, mid+1, R);
sum[x] = sum[lx] + sum[rx];
}
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(sum,0,sizeof sum);
memset(cover,0,sizeof cover);
for(int i=1;i<=n;i++) {
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
Rank[i*2-1] = y1; Rank[i*2] = y2;
p[i*2-1] = node(x1, y1, y2, 1);
p[i*2] = node(x2, y1, y2, -1);
}
sort(p+1,p+1+n*2,cmp);
setRank();
double area = 0;
Cover(1, p[1].in, getRank(p[1].y1), getRank(p[1].y2)-1, 1, I);
for(int i=2;i<=n*2;i++){
area += (p[i].x - p[i-1].x) * sum[1];
Cover(1, p[i].in, getRank(p[i].y1), getRank(p[i].y2)-1, 1, I);
}
printf("%.2lf\n",area+eps);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: