HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化
Posted h_z_cong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化相关的知识,希望对你有一定的参考价值。
题目链接:https://vjudge.net/problem/HDU-1255
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.
注意:本题的输入数据较多,推荐使用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
题解:
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const double EPS = 1e-8; 15 const int INF = 2e9; 16 const LL LNF = 2e18; 17 const int MAXN = 1e5+10; 18 19 struct line 20 { 21 double le, ri, h; 22 int id; 23 bool operator<(const line &a){ 24 return h<a.h; 25 } 26 }Line[MAXN]; 27 28 int cnt[MAXN<<2]; 29 double sum[MAXN<<2], len[MAXN], X[MAXN]; 30 31 void push_up(int u, int l, int r) 32 { 33 if(cnt[u]>=2) 34 { 35 sum[u] = X[r] - X[l]; 36 len[u] = X[r] - X[l]; 37 } 38 else if(cnt[u]==1) 39 { 40 sum[u] = len[u*2]+len[u*2+1]; 41 len[u] = X[r] - X[l]; 42 } 43 else // if(cnt[u]==0) 44 { 45 sum[u] = sum[u*2]+sum[u*2+1]; 46 len[u] = len[u*2]+len[u*2+1]; 47 } 48 } 49 50 void add(int u, int l, int r, int x, int y, int val) 51 { 52 if(x<=l && r<=y) 53 { 54 cnt[u] += val; 55 push_up(u, l, r); 56 return; 57 } 58 59 int mid = (l+r)>>1; 60 if(x<=mid-1) add(u*2, l, mid, x, y, val); 61 if(y>=mid+1) add(u*2+1, mid, r, x, y, val); 62 push_up(u, l, r); 63 } 64 65 int main() 66 { 67 int n, T; 68 scanf("%d", &T); 69 while(T--) 70 { 71 scanf("%d", &n); 72 for(int i = 1; i<=n; i++) 73 { 74 double x1, y1, x2, y2; 75 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 76 Line[i].le = Line[i+n].le = x1; 77 Line[i].ri = Line[i+n].ri = x2; 78 Line[i].h = y1; Line[i+n].h = y2; 79 Line[i].id = 1; Line[i+n].id = -1; 80 X[i] = x1; X[i+n] = x2; 81 } 82 83 sort(Line+1, Line+1+2*n); 84 sort(X+1, X+1+2*n); 85 int m = unique(X+1, X+1+2*n) - (X+1); 86 87 memset(sum, 0, sizeof(sum)); 88 memset(cnt, 0, sizeof(cnt)); 89 memset(len, 0, sizeof(len)); 90 double ans = 0; 91 for(int i = 1; i<=2*n-1; i++) 92 { 93 int l = upper_bound(X+1, X+1+m, Line[i].le) - (X+1); 94 int r = upper_bound(X+1, X+1+m, Line[i].ri) - (X+1); 95 add(1, 1, m, l, r, Line[i].id); 96 ans += sum[1]*(Line[i+1].h-Line[i].h); 97 } 98 printf("%.2f\n", ans); 99 } 100 }
以上是关于HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化的主要内容,如果未能解决你的问题,请参考以下文章