覆盖的面积
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3402 Accepted Submission(s): 1663
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
Recommend
Ignatius.L
线段树维护x轴上覆盖长度(一次/多次)
样例我输出7.62竟然过了
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#define oform1 "%I64d"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#define oform1 "%lld"
#endif
#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define S64I1(a) scanf(iform1, &(a))
#define P64I1(a) printf(oform1, (a))
#define FOR(i, s, t) for(int (i)=(s); (i)<(t); (i)++)
const int INF = 0x3f3f3f3f;
const double eps = 10e-9;
const double PI = (4.0*atan(1.0));
const int maxn = 4000 + 20;
const int maxo = maxn * 4;
struct Seg {
double l, r, h, d;
Seg(double ll=0, double rr=0, double hh=0, int dd=-1) : l(ll), r(rr), h(hh), d(dd) {}
};
int n;
int num = 0;
int segNum = 0;
Seg segs[maxn*2];
double X[maxn*4];
int cover[maxo];
double once[maxo];
double more[maxo];
bool cmp(Seg a, Seg b) {
return a.h < b.h;
}
void pushUp(int o, int L, int R) {
if(cover[o] > 1) {
more[o] = once[o] = X[R+1] - X[L];
} else if(cover[o] == 1) {
once[o] = X[R+1] - X[L];
more[o] = once[o<<1] + once[o<<1|1];
} else if(R == L) {
once[o] = more[o] = 0;
} else {
once[o] = once[o<<1] + once[o<<1|1];
more[o] = more[o<<1] + more[o<<1|1];
}
}
int ql, qr, qv;
void update(int o, int L, int R) {
if(ql <= L && R <= qr) {
cover[o] += qv;
pushUp(o, L, R);
return ;
}
int M = L + (R-L) / 2;
if(ql <= M) update(o<<1, L, M);
if(M < qr) update(o<<1|1, M+1, R);
pushUp(o, L, R);
}
int Bin(double x) {
int l = 0;
int r = num-1;
while(l <= r) {
int m = (r+l)>>1;
if(fabs(X[m]-x) < eps) return m;
else if(X[m] < x) l = m+1;
else r = m-1;
}
return -1;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
memset(cover, 0, sizeof(cover));
memset(once, 0, sizeof(once));
memset(more, 0, sizeof(more));
segNum = num = 0;
for(int i=0; i<n; i++) {
double x1, y1, x2, y2;
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
segs[segNum++] = Seg(x1, x2, y1, 1);
segs[segNum++] = Seg(x1, x2, y2, -1);
X[num++] = x1;
X[num++] = x2;
}
sort(X, X+num);
int tnum = 1;
for(int i=1; i<num; i++) {
if(fabs(X[i]-X[i-1]) > eps) X[tnum++] = X[i];
}
num = tnum;
double ans = 0;
sort(segs, segs+segNum, cmp);
for(int i=0; i<segNum-1; i++) {
ql = Bin(segs[i].l);
qr = Bin(segs[i].r) - 1;
qv = segs[i].d;
if(ql <= qr) update(1, 0, num-1);
ans += more[1] * (segs[i+1].h - segs[i].h);
}
printf("%.2lf\n", ans);
}
return 0;
}