UVA - 688(线段树+扫描线)

本文介绍了一种通过扫描线算法计算多个矩形交并面积的方法。利用离散坐标系中的矩形中心及中心到边的距离作为输入,通过构建线段树进行区间覆盖计算,最终得出所有矩形的总面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给你n个矩形的中心和中心到边的距离让你求面积并

题解:套一下模板就好了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 2e3+5; 
struct node{
    double x1,x2,y;
    int f;
}E[2*maxn];
double x[2*maxn];
struct tree{
    double l,r;
    int flag;
    int cover;
}t[maxn*8];
bool cmp(node a,node b){
    return a.y < b.y;
}
void built(int i,int l,int r){
    t[i].l = x[l],t[i].r = x[r];
    t[i].cover = t[i].flag = 0;
    if(l+1 >= r){
        t[i].flag = 1;
        return ;
    }
    int mid = (l+r)/2;
    built(2*i,l,mid);
    built(2*i+1,mid,r);
}
double update(int i,double l,double r,double y,int f){
    if(t[i].flag){ 
        if(t[i].r <= r && t[i].l >= l)
            t[i].cover += f;
        if(t[i].cover)
            return t[i].r - t[i].l;
        else{
            return 0;
        }
    }
    double s1 = update(2*i,l,r,y,f);
    double s2 = update(2*i+1,l,r,y,f);
    return s1+s2;
}
int main(){
    int t = 1;
    int n;
    double x1,y1,r;
    while(scanf("%d",&n) && n){
        int m = 1;
        int d = 0;
        for(int i = 1; i <= n; i++){
            scanf("%lf%lf%lf",&x1,&y1,&r);
            if(fabs(r-0)<=1e-6){
            	d++;
            	continue;
			}
            x[m-1] = E[m].x1 = E[m+1].x1 = x1-r;
            x[m] = E[m].x2 = E[m+1].x2 = x1+r;
            E[m].f = 1;
            E[m+1].f = -1;
            E[m+1].y = y1+r;
            E[m].y = y1-r;
            m += 2;
        }
        n-=d;
        sort(x,x+2*n);
        sort(E+1,E+1+2*n,cmp);
        int k = 1;
        for(int i = 1; i < 2*n; i++)
            if(x[i] != x[i-1])
                x[k++] = x[i];
        built(1,0,k-1);
        double area = 0;
        for(int i = 1; i < 2*n; i++)
            area += (E[i+1].y - E[i].y)*update(1,E[i].x1,E[i].x2,E[i].y,E[i].f);
        printf("%d %.2lf\n",t++,area);
    }
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值