HDU 1255 覆盖的面积

个人博客→TanJX的自留地

覆盖的面积

给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
在这里插入图片描述

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

题意

中文题

题解

扫描线,不再是用覆盖过一次的长度而是用覆盖两次的长度*两条扫描线之间的坐标差

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <queue>

using namespace std;
#define me(x,y) memset(x,y,sizeof x)
#define lson rt<<1
#define rson rt<<1|1
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
typedef long long ll;
const int maxn = 2010;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
#define eps 0.000000001

int n;
double Hash[maxn<<1];

struct Node{
    double l,r,x;
    int fg;
    Node(){}
    Node(double _l,double _r,double _x,double _fg) : l(_l),r(_r),x(_x),fg(_fg){}
    bool operator < (const Node &a) const{
        return x < a.x;
    }
}node[maxn<<2];

struct N{
    double len1,len2;
    int col;
    N(){}
    N(double _len1,double _len2,int _col):len1(_len1),len2(_len2),col(_col){}
}nn[maxn<<2];

void build(int rt,int l,int r){
    nn[rt] = N(0,0,0);
    if(l == r){
        return ;
    }
    int mid = (l + r) >> 1;
    build(lson,l,mid);
    build(rson,mid+1,r);
}
void Pushup(int rt,int l,int r){
    if(nn[rt].col){
        nn[rt].len1 = Hash[r+1] - Hash[l];
    }
    else if(l == r){
        nn[rt].len1 = 0;
    }
    else{
        nn[rt].len1 = nn[lson].len1 + nn[rson].len1;
    }
    if(nn[rt].col > 1){
        nn[rt].len2 = Hash[r+1] - Hash[l];
    }
    else if(l == r){
        nn[rt].len2 = 0;
    }
    else if(nn[rt].col == 1){
        nn[rt].len2 = nn[lson].len1 + nn[rson].len1;
    }
    else{
        nn[rt].len2 = nn[lson].len2 + nn[rson].len2;
    }
}

void update(int rt,int L,int R,int l,int r,int val){
    if(L <= l && R >= r){ 
        nn[rt].col += val;
        Pushup(rt,l,r);
        return ;
    }
    int mid = (l + r) >> 1;
    if(L <= mid){
        update(lson,L,R,l,mid,val);
    }
    if(R > mid){
        update(rson,L,R,mid+1,r,val);
    }
    Pushup(rt,l,r);
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        scanf("%d",&n);
        me(nn,0);
        int m = 0;
        double sum = 0;
        for(int i = 1;i <= n; i++){
            double x1,x2,y1,y2;
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            Hash[m] = y1;
            node[m++] = Node(y1,y2,x1,1);
            Hash[m] = y2;
            node[m++] = Node(y1,y2,x2,-1);
        }
        int d = 1;
        sort(Hash,Hash+m);
        sort(node,node+m);
        for(int i = 1; i < m; i++){
            if(Hash[i-1] != Hash[i]){
                Hash[d++] = Hash[i];
            }
        }
        for(int i = 0; i < m; i++){
            int l = lower_bound(Hash,Hash+d,node[i].l)-Hash; 
            int r = lower_bound(Hash,Hash+d,node[i].r)-Hash-1;
            update(1,l,r,0,d-1,node[i].fg);
            sum += nn[1].len2*(node[i+1].x - node[i].x);
        }
        printf("%.2lf\n",sum+eps);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41746268/article/details/86606122
今日推荐