POJ1151基本的扫描线求面积

题意:
     给定n个矩形的对角坐标,分别是左下和右上,浮点型,求矩形覆盖的面积。


思路:

      基本的线段树扫描线求面积,没有坑点,不解释了,提示一点,有的题尤其是线段树扫描线的题需要离散化的时候建议二分去找,别map,记得之前map超时过很多次,但不是针对这个题目,这个题数据量不大,怎么都行,发现codeblock这个编译器定义宏然后在定义结构体的时候变量名字相同导致编译不过去,我之前用的DEV也是这么写的,记得能编译过去,不知道为啥。

#include<stdio.h>
#include<string.h>
#include<algorithm>

//#define l ,mid ,t << 1
//#define mid ,r ,t << 1 | 1
#define N 105

using namespace std;

typedef struct
{
  double l ,r ,h ,mk;
}EDGE;

double num[105*2*2] ,tmp[105*2*2];
double len[105*2*2*4];
int cnt[105*2*2*4];
EDGE E[105*2];

bool camp(EDGE a ,EDGE b)
{
    return a.h < b.h || a.h == b.h && a.mk < b.mk;
}

void PushUp(int l ,int r ,int t)
{
    if(cnt[t]) len[t] = num[r] - num[l];
    else if(l + 1 == r) len[t] = 0;
    else len[t] = len[t<<1] + len[t<<1|1];
}

void Update(int l ,int r ,int t ,int a ,int b ,int c)
{
    if(a == l && b == r)
    {
        cnt[t] += c;
        PushUp(l ,r ,t);
        return ;
    }
    int mid = (l + r) >> 1;
    if(b <= mid) Update(l,mid ,t << 1 ,a ,b ,c);
    else if(a >= mid) Update(mid ,r ,t << 1 | 1 ,a ,b ,c);
    else
    {
        Update(l ,mid ,t << 1 ,a ,mid ,c);
        Update(mid ,r ,t << 1 | 1 ,mid  ,b ,c);
    }
    PushUp(l ,r ,t);
}

void BuidTree()
{
    memset(cnt ,0 ,sizeof(cnt));
    memset(len ,0 ,sizeof(len));
    return ;
}

int search2(double now ,int n)
{
    int low = 1 ,up = n ,mid ,ans;
    while(low <= up)
    {
        mid = (low + up) >> 1;
        if(now <= num[mid])
        {
            ans = mid;
            up = mid - 1;
        }
        else low = mid + 1;
    }
    return ans;
}



int main ()
{
    int i ,n ,id ,cas = 1;
    double x1 ,y1 ,x2 ,y2;
    double Ans;
    while(~scanf("%d" ,&n) && n)
    {
        for(id = 0 ,i = 1 ;i <= n ;i ++)
        {
            scanf("%lf %lf %lf %lf" ,&x1 ,&y1 ,&x2 ,&y2);
            E[++id].l = x1;
            E[id].r = x2 ,E[id].h = y1 ,E[id].mk = 1;
            tmp[id] = x1;

            E[++id].l = x1;
            E[id].r = x2 ,E[id].h = y2 ,E[id].mk = -1;
            tmp[id] = x2;
        }
        sort(E + 1 ,E + id + 1 ,camp);
        sort(tmp + 1 ,tmp + id + 1);

        int n2 = n * 2;
        for(id = 0 ,i = 1 ;i <= n2 ;i ++)
        {
            if(i == 1 || tmp[i] != tmp[i-1])
            num[++id] = tmp[i];
        }
        BuidTree();
        E[0].h = E[1].h;
        Ans = 0;
        for(i = 1 ;i <= n2 ;i ++)
        {
            Ans += len[1] * (E[i].h - E[i-1].h);
            int l = search2(E[i].l ,id);
            int r = search2(E[i].r ,id);
            Update(1 ,id ,1 ,l ,r ,E[i].mk);
        }
        printf("Test case #%d
" ,cas ++);
        printf("Total explored area: %.2lf

" ,Ans);
    }
    return 0;

}



原文地址:https://www.cnblogs.com/csnd/p/12062425.html