hdu 1542 Atlantis

来源:互联网 发布:深圳启讯网络骗局 编辑:程序博客网 时间:2024/06/04 18:15

Problem

acm.hdu.edu.cn/showproblem.php?pid=1542

Meaning

给出若干个平面上的矩形,问总的面积(重叠部分算一次)

Analysis

扫描线求矩形面积并。
算法中的离散化的一个作用是:将连续的实数坐标转成离散的整数(处理浮点数),从而可以用线段树来维护。
这篇是从左到右扫(从下往上扫看上篇)

Code

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 100;struct seg{    double l, h, x;    int v;    seg() {}    seg(double _l, double _h, double _x, int _v):        l(_l), h(_h), x(_x), v(_v) {}    bool operator < (const seg &rhs) const    {        return x < rhs.x;    }} s[N<<1];int cvr[N<<3];double y[N<<1], len[N<<3];void pushup(int l, int r, int rt){    if(cvr[rt])        len[rt] = y[r] - y[l];    else if(l + 1 >= r)        len[rt] = 0.0;    else        len[rt] = len[rt<<1] + len[rt<<1|1];}void update(int ul, int ur, int v, int l, int r, int rt){    if(ul <= l && r <= ur)    {        cvr[rt] += v;        pushup(l, r, rt);        return;    }    int m = l + r >> 1;    if(ul < m)        update(ul, ur, v, l, m, rt<<1);    if(ur > m)        update(ul, ur, v, m, r, rt<<1|1);    pushup(l, r, rt);}int main(){    for(int kase = 1, n; scanf("%d", &n), n; ++kase)    {        for(int i = 0; i < n; ++i)        {            double xl, xr, yl, yr;            scanf("%lf%lf%lf%lf", &xl, &yl, &xr, &yr);            s[i] = seg(yl, yr, xl, 1);            s[i+n] = seg(yl, yr, xr, -1);            y[i] = yl;            y[i+n] = yr;        }        n <<= 1;        sort(s, s + n);        sort(y, y + n);        int m = unique(y, y + n) - y;        memset(cvr, 0, sizeof cvr);        memset(len, 0, sizeof len);        double ans = 0.0;        for(int i = 0, l, h; i < n - 1; ++i)        {            l = lower_bound(y, y + m, s[i].l) - y;            h = lower_bound(y, y + m, s[i].h) - y;            update(l, h, s[i].v, 0, m-1, 1);            ans += len[1] * (s[i+1].x - s[i].x);        }        printf("Test case #%d\nTotal explored area: %.2f\n\n", kase, ans);    }    return 0;}
原创粉丝点击