hdu 1542 线段树之扫描线之面积并

点击打开链接

题意:给你n个矩形,求它们的面积,重复的不重复计算

思路:用线段树的扫描线完成,将X坐标离散化后,从下到上扫描矩形,进行各种处理,看代码注释把

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e3+10;
#define mm(a) memset(a,0,sizeof(a))
int num1[maxn*4];
double num[maxn*4],X[maxn*4];
struct edge{
    double l,r,h;
    int s;//s为1是下边,s为-1是上边
    edge(){};
    edge(double a,double b,double c,int d) : l(a),r(b),h(c),s(d){}
    bool operator<(const edge &n)const{
        return h<n.h;
    }
}ss[maxn];
void pushup(int le,int ri,int node){
    if(num1[node]) num[node]=X[ri+1]-X[le];//在更新的时候,可能两个矩阵有重叠,这样就不能像以前那么更新,而是将le和ri传入
    else if(le==ri) num[node]=0;           //然后将X[ri+1]-X[le]的值进行更新,避免了重复的长度
    else num[node]=num[node<<1]+num[node<<1|1];
}
void update(int l,int r,int add,int le,int ri,int node){
    if(l<=le&&ri<=r){
        num1[node]+=add;//与懒惰标记类似
        pushup(le,ri,node);
        return ;
    }
    int t=(le+ri)>>1;
    if(l<=t) update(l,r,add,le,t,node<<1);
    if(r>t) update(l,r,add,t+1,ri,node<<1|1);
    pushup(le,ri,node);
}
int main(){
    int n,t=1;
    while(scanf("%d",&n)!=-1){
        if(n==0) break;
        double a,b,c,d;
        int k=0;
        for(int i=0;i<n;i++){
            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
            X[k]=a;
            ss[k++]=edge(a,c,b,1);
            X[k]=c;
            ss[k++]=edge(a,c,d,-1);
        }
        sort(X,X+k);
        sort(ss,ss+k);
        int k1=1;
        for(int i=1;i<k;i++){//对X进行离散化
            if(X[i]!=X[i-1]) X[k1++]=X[i];
        }
        mm(num);mm(num1);
        double ans=0;
        for(int i=0;i<k-1;i++){
            int l=lower_bound(X,X+k1,ss[i].l)-X;
            int r=lower_bound(X,X+k1,ss[i].r)-X-1;
            update(l,r,ss[i].s,0,k1-1,1);
            ans+=num[1]*(ss[i+1].h-ss[i].h);//num[1]为当前横坐标的总长度
        }
        printf("Test case #%d\nTotal explored area: %.2f\n\n",t++,ans);
    }
    return 0;
}
时间: 2024-12-28 17:47:50

hdu 1542 线段树之扫描线之面积并的相关文章

HDU 3642 线段树+离散化+扫描线

题意:给你N个长方体的左下角和右上角坐标,问你空间中有多少体积是被大于两个不同的立方体覆盖的.x,y~10^6 z~500 考虑到给的z比较小,所以可以直接枚举z,然后跑二维的扫描线就好. 关于处理被不同的线段覆盖三次的问题,可以维护四个信息,cnt,once,twice,more,然后相互推出结果就好. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #

hdu 1542 线段树+扫描线

啦啦啦~继续学算法 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7349    Accepted Submission(s): 3231 Problem Description There are several

HDU 1542 线段树+扫描线+离散化

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8327    Accepted Submission(s): 3627 Problem Description There are several ancient Greek texts that contain descriptions of the fabled is

hdu 1556(线段树之扫描线)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556 Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11361    Accepted Submission(s): 5659 Problem Description N个气球排成一排,从左到右依次编号为1,2

HDU 1542 Atlantis 线段树+离散化+扫描线

题意:给出一些矩形的最上角坐标和右下角坐标,求这些矩形的面积并. NotOnlySuccess 线段树专辑中扫描线模板题,弱智的我对着大大的代码看了一下午才搞懂. 具体见思路见注释=.= #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define lson rt<<1,l,mid #define rson rt<<1|1,mid

HDU 1542 Atlantis (线段树求矩阵覆盖面积)

题意:给你n个矩阵求覆盖面积. 思路:看了别人的结题报告 给定一个矩形的左下角坐标和右上角坐标分别为:(x1,y1).(x2,y2),对这样的一个矩形,我们构造两条线段,一条定位在x1,它在y坐标的区间是[y1,y2],并且给定一个cover域值为1:另一条线段定位在x2,区间一样是[y1,y2],给定它一个cover值为-1.根据这样的方法对每个矩形都构造两个线段,最后将所有的线段根据所定位的x从左到右进行排序 #include <iostream> #include <stdio.h

【HDU 1542】Atlantis(线段树+离散化,矩形面积并)

求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<cstdio> #include<cstring> #define dd double #define ll long long #define N 201 using namespace std; struct P{dd s,e,h;int f;}p[N]; struct Tree{dd s

hdu 1255(线段树 扫描线) 覆盖的面积

http://acm.hdu.edu.cn/showproblem.php?pid=1255 典型线段树辅助扫描线,顾名思义扫描线就是相当于yy出一条直线从左到右(也可以从上到下)扫描过去,此时先将所有的横坐标和纵坐标排序 因为是从左到右扫描,那么横坐标应该离散化一下 当扫描线依次扫描的时候,依次扫描到的纵区间在线段树中查找,依据是上边还是下边记录,上边就是-1,下边就是+1, 如果某区间记录值为0的时候,代表没有被覆盖,为1的时候代表覆盖一次,为2代表覆盖两次(不会出现为负数的情况) 最后将依

hdu1255--覆盖的面积(线段树+离散化+扫描线)

E - 覆盖的面积 Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含