码迷,mamicode.com
首页 > 其他好文 > 详细

HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化

时间:2017-10-28 12:44:07      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:cstring   ret   output   idt   题目   namespace   pre   style   center   

题目链接: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 }
View Code

 

HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化

标签:cstring   ret   output   idt   题目   namespace   pre   style   center   

原文地址:http://www.cnblogs.com/DOLFAMINGO/p/7746244.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!