HDU - 1255 覆盖的面积(线段树 + 扫描线)

本文介绍了一个基于矩形面积计算的问题,并通过离散化的方法进行优化解决。利用C++实现了一种有效算法,该算法可以处理多个矩形的重叠问题并计算总面积。

 HDU - 1255 题目

题意: 额中文题

基本就是求矩形面积,改一点就好了。

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>

using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
const double eps = 10e-6;
const int maxn = 1050;
struct node
{
    double x,y1,y2;int v;
    node(){}
    node(double a,double b,double c,int d)
    {   x = a; y1 = b; y2 = c; v = d;}
}x[maxn<<1];

double y[maxn<<3];  //离散
map<double, int> id;

int cover[maxn<<3];
double len[maxn<<3] , ylen[maxn<<1];

int xnum,ynum;

bool cmp(node a,node b)
{   return a.x < b.x;   }
void pre()  //离散化
{
    sort(x, x + xnum, cmp);
    sort(y, y + ynum);
    ynum = unique(y, y + ynum) - y;
    for(int i = 0; i < ynum; i++)
    {
        id[ y[i] ] = i+1;
        ylen[i+1] = i == ynum-1? 0 : y[i+1] - y[i];
    }
}
void up(int ul,int ur,int id,int l,int r,int v)
{
    if(r < ul || l > ur) return;
    if(l >= ul && r <= ur)
    {
        cover[id] += v;
        if(l == r)
        {
            if(cover[id] >= 2){len[id] = ylen[l];return;}
            else {len[id] = 0; return;}
        }
    }
    int m = l+r>>1;
    if(ul <= m) up(ul, ur, id << 1, l, m, v);
    if(ur >  m) up(ul, ur, id<<1|1, m+1, r, v);

    len[id] = len[id<<1] + len[id<<1|1];
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        xnum = 0, ynum = 0;
        scanf("%d",&n);
        for(int i = 1; i <= n ; i++)
        {
            double a,b,c,d;
            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
            x[xnum++] = node(a,b,d,1);  x[xnum++] = node(c,b,d,-1);
            y[ynum++] = b; y[ynum++] = d;
        }
        pre();
        double ret = 0;
        double li = x[0].x, last = 0;
        for(int i = 0; i < xnum; i++)
        {
            ret += (x[i].x-li)*last;
            int id1 = id[x[i].y1], id2 = id[x[i].y2];
            up(id1,id2-1,1,1,ynum,x[i].v);
            last = len[1];
            li = x[i].x;
        }
        printf("%.2f\n",ret+eps);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值