HDU1255 扫描线 矩形交面积 离散化

Posted LuZhiyuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU1255 扫描线 矩形交面积 离散化相关的知识,希望对你有一定的参考价值。

覆盖的面积

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5595    Accepted Submission(s): 2810


Problem Description
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.

技术分享
 

 

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
 

 

Author
Ignatius.L & weigang Lee
 

题意:

给出矩形左下和右上角的坐标,求矩形交的面积。

代码:

//cnt[rt]>=2的一定是覆盖过两次以上的,直接计算。cnt[rt]==1时,如果rt的左右儿子
//被覆盖过大于等于1次,那么再被他们父亲覆盖上就是覆盖过两次了,值是左右儿子被
//覆盖过一次的长度的和。cnt[rt]==0照常更新。sum2记录覆盖过两次以上的边的长度。
//sum1记录覆盖过一次的边的长度。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2005;
double sum1[maxn*4],sum2[maxn*4],mp[maxn];
int cnt[maxn*4];
struct node{
    double l,r,h;
    int d;
    node(){}
    node(double a,double b,double c,int d):l(a),r(b),h(c),d(d){}
    bool operator < (const node &p)const{
        if(h==p.h) return d>p.d;
        return h<p.h;
    }
}nodes[maxn*4];
int Bsearch(double a,int b,double *c)
{
    int l=0,r=b-1,mid;
    while(l<=r){
        mid=(l+r)>>1;
        if(c[mid]==a) return mid;
        else if(c[mid]>a) r=mid-1;
        else l=mid+1;
    }
    return -1;
}
void Pushup(int l,int r,int rt)
{
    if(cnt[rt]){
        sum1[rt]=mp[r+1]-mp[l];
        if(cnt[rt]==1)
            sum2[rt]=sum1[rt<<1]+sum1[rt<<1|1];
        else sum2[rt]=mp[r+1]-mp[l];
    }
    else if(l==r) sum1[rt]=sum2[rt]=0;
    else{
        sum1[rt]=sum1[rt<<1]+sum1[rt<<1|1];
        sum2[rt]=sum2[rt<<1]+sum2[rt<<1|1];
    }
}
void Update(int ql,int qr,int v,int l,int r,int rt)
{
    if(ql<=l&&qr>=r){
        cnt[rt]+=v;
        Pushup(l,r,rt);
        return;
    }
    //if(l==r) return;
    int m=(l+r)>>1;
    if(ql<=m) Update(ql,qr,v,l,m,rt<<1);
    if(qr>m) Update(ql,qr,v,m+1,r,rt<<1|1);
    Pushup(l,r,rt);
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        int m=0,nu=0;
        double x1,y1,x2,y2;
        memset(sum1,0,sizeof(sum1));
        memset(sum2,0,sizeof(sum2));
        memset(cnt,0,sizeof(cnt));
        for(int i=0;i<n;i++){
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            nodes[m++]=node(x1,x2,y1,1);
            nodes[m++]=node(x1,x2,y2,-1);
            mp[nu++]=x1;mp[nu++]=x2;
        }
        sort(mp,mp+nu);
        nu=unique(mp,mp+nu)-mp;
        sort(nodes,nodes+m);
        double ans=0;
        for(int i=0;i<m-1;i++){
            int lef=Bsearch(nodes[i].l,nu,mp);
            int rig=Bsearch(nodes[i].r,nu,mp)-1;
            if(lef<=rig)
                Update(lef,rig,nodes[i].d,0,nu-1,1);
            ans+=sum2[1]*(nodes[i+1].h-nodes[i].h);
        }
        printf("%.2lf\n",ans);
    }
    return 0;
}

 









以上是关于HDU1255 扫描线 矩形交面积 离散化的主要内容,如果未能解决你的问题,请参考以下文章

矩形面积并矩形面积交矩形周长并(线段树扫描线总结)(转载)

HDU - 1255 扫描线+离散化进阶

HDU3642 Get The Treasury —— 求矩形交体积 线段树 + 扫描线 + 离散化

HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

HDU 1542.Atlantis-线段树求矩形面积并(离散化扫描线/线段树)-贴模板

扫描线,线段树,离散化——HDU - 1542