给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
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 <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include <ctype.h> 6 #include <set> 7 #include <map> 8 #include <queue> 9 #include <stack> 10 #include <iostream> 11 using namespace std; 12 #define bug printf("****** "); 13 #define rtl rt<<1 14 #define rtr rt<<1|1 15 typedef long long LL; 16 const int maxn = 1e4 + 10; 17 struct LINE { 18 double x, y1, y2; 19 int flag; 20 } line[maxn]; 21 int cmp(LINE a, LINE b) { 22 return a.x < b.x; 23 } 24 struct node { 25 double x, l, r, pre; 26 int flag, cover; 27 } tree[maxn << 2]; 28 double y[maxn]; 29 void build(int l, int r, int rt ) { 30 tree[rt].l = y[l], tree[rt].r = y[r]; 31 tree[rt].pre = 0, tree[rt].cover = 0, tree[rt].flag = 0; 32 if (l + 1 == r) { 33 tree[rt].flag = 1; 34 return ; 35 } 36 int m = (l + r) >> 1; 37 build(l, m, rtl); 38 build(m, r, rtr); 39 } 40 double query(int rt, double x, double y1, double y2, int flag) { 41 if (tree[rt].l >= y2 || tree[rt].r <= y1) return 0; 42 if (tree[rt].flag == 1) { 43 if (tree[rt].cover > 1) { 44 double pre = tree[rt].pre; 45 double ans = (x - pre) * (tree[rt].r - tree[rt].l); 46 tree[rt].pre = x; 47 tree[rt].cover += flag; 48 return ans; 49 } else { 50 tree[rt].cover += flag; 51 tree[rt].pre = x; 52 return 0; 53 } 54 } 55 return query(rtl, x, y1, y2, flag) + query(rtr, x, y1, y2, flag); 56 } 57 int main() { 58 int t, n; 59 scanf("%d", &t); 60 while(t--) { 61 scanf("%d", &n); 62 int cnt = 0; 63 for (int i = 0 ; i < n ; i++) { 64 double x1, y1, x2, y2; 65 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 66 y[cnt] = y1; 67 line[cnt].x = x1; 68 line[cnt].y1 = y1; 69 line[cnt].y2 = y2; 70 line[cnt++].flag = 1; 71 y[cnt] = y2; 72 line[cnt].x = x2; 73 line[cnt].y1 = y1; 74 line[cnt].y2 = y2; 75 line[cnt++].flag = -1; 76 } 77 sort(y, y + cnt ); 78 sort(line, line + cnt, cmp); 79 build(0, cnt-1, 1); 80 double ans = 0; 81 for (int i = 0 ; i < cnt ; i++) 82 ans += query(1, line[i].x, line[i].y1, line[i].y2, line[i].flag); 83 printf("%.2f ", ans); 84 } 85 return 0; 86 }