zoukankan      html  css  js  c++  java
  • Hdu1255 覆盖的面积

    覆盖的面积

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 6453    Accepted Submission(s): 3283


    Problem Description
    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.

     
    Input
    输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.

    注意:本题的输入数据较多,推荐使用scanf读入数据.
     
    Output
    对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.
     
    Sample Input
    2 5 1 1 4 2 1 3 3 7 2 1.5 5 4.5 3.5 1.25 7.5 4 6 3 10 7 3 0 0 1 1 1 0 2 1 2 0 3 1
     
    Sample Output
    7.63 0.00
     
    Author
    Ignatius.L & weigang Lee
     
    Recommend
    Ignatius.L   |   We have carefully selected several similar problems for you:  1698 1166 1540 1394 1754 
    分析:和Hdu1542类似,只是要求覆盖两次及以上的面积,那么线段树就要多记录一些东西.
              扫描线的线段树有点奇怪,修改的标记不会下传,标记的意义是当前区间被完整地覆盖了多少次,我们可以根据这个标记来求这个区间覆盖了至少一次的长度和至少两次的长度.分点和线来考虑,如果当前考虑的区间是个点,那么答案肯定是0,否则看标记,如果标记大于0了,那么覆盖了至少一次的长度可以直接算出来,如果标记大于1了,至少覆盖两次的长度也可以直接算出来.如果标记正好等于1,当前区间被完整地覆盖了一次,找到子区间被覆盖了至少一次的区间长度,两个子区间加起来就是答案.其它情况都要从子区间得到,类似于pushup.
              数组至少要开2倍......数组开小了竟然WA了不是RE......
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 5010;
    
    struct node
    {
        double l, r, h;
        int id;
    }e[maxn * 2];
    
    int tot, T, n, cnt, tag[maxn << 2];
    double ans, X[maxn], XX[maxn], sum2[maxn << 2], sum[maxn << 2];
    
    bool cmp(node a, node b)
    {
        return a.h < b.h;
    }
    
    int find(double x)
    {
        int l = 1, r = cnt;
        while (l <= r)
        {
            int mid = (l + r) >> 1;
            if (XX[mid] == x)
                return mid;
            else
            if (XX[mid] > x)
                r = mid - 1;
            else
                if (XX[mid] < x)
                    l = mid + 1;
        }
        return 0;
    }
    
    void pushup(int o, int l, int r)
    {
        if (tag[o])
            sum[o] = XX[r + 1] - XX[l];
        else
            if (l == r)
                sum[o] = 0;
            else
                sum[o] = sum[o * 2] + sum[o * 2 + 1];
    
        if (tag[o] > 1)
            sum2[o] = XX[r + 1] - XX[l];
        else
            if (l == r)
                sum2[o] = 0;
            else
                if (tag[o] == 1)
                    sum2[o] = sum[o * 2] + sum[o * 2 + 1];
                else
                    sum2[o] = sum2[o * 2 + 1] + sum2[o * 2];
    }
    
    void update(int o, int l, int r, int x, int y, int v)
    {
        if (x <= l && r <= y)
        {
            tag[o] += v;
            pushup(o, l, r);
            return;
        }
        int mid = (l + r) >> 1;
        if (x <= mid)
            update(o * 2, l, mid, x, y, v);
        if (y > mid)
            update(o * 2 + 1, mid + 1, r, x, y, v);
        pushup(o, l, r);
    }
    
    int main()
    {
        scanf("%d", &T);
        while (T--)
        {
            memset(tag, 0, sizeof(tag));
            memset(sum, 0, sizeof(sum));
            memset(sum2, 0, sizeof(sum2));
            memset(X, 0, sizeof(X));
            memset(XX, 0, sizeof(XX));
            ans = 0.0;
            cnt = tot = 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);
                e[++tot].l = a;
                e[tot].r = c;
                e[tot].h = b;
                e[tot].id = 1;
                X[tot] = a;
                e[++tot].l = a;
                e[tot].r = c;
                e[tot].h = d;
                e[tot].id = -1;
                X[tot] = c;
            }
            sort(e + 1, e + 1 + tot, cmp);
            sort(X + 1, X + 1 + tot);
            XX[1] = X[1];
            cnt = 1;
            for (int i = 2; i <= tot; i++)
                if (X[i] != X[i - 1])
                    XX[++cnt] = X[i];
            for (int i = 1; i < tot; i++)
            {
                int l = find(e[i].l), r = find(e[i].r) - 1;
                update(1, 1, cnt, l, r, e[i].id);
                ans += (e[i + 1].h - e[i].h) * sum2[1];
            }
            printf("%.2lf
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    hdu 1240:Asteroids!(三维BFS搜索)
    hdu 2199:Can you solve this equation?(二分搜索)
    hdu 1195:Open the Lock(暴力BFS广搜)
    【ACM
    hrbustoj 1161:Leyni(树状数组练习)
    时间作为横轴的图表(morris.js)超越昨天的自己系列(8)
    Bean实例化(Spring源码阅读)-我们到底能走多远系列(33)
    Sharded实现学习-我们到底能走多远系列(32)
    初始化IoC容器(Spring源码阅读)-我们到底能走多远系列(31)
    一致性哈希算法 应用场景(转)
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8010601.html
Copyright © 2011-2022 走看看