• 线段树


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



    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:  ry 
     * Created Time:  2017/10/24 8:57:44
     * File Name: 1.cpp
     */
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    #include <time.h>
    using namespace std;
    const int eps = 3e+5;
    const double pi = acos(-1.0);
    const int inf = 0x3f3f3f3f;
    #define Max(a,b) a>b?a:b
    #define Min(a,b) a>b?b:a
    #define ll long long
    
    struct seg
    {
        double l, r, h;
        int f;
    }po[eps];
    double x[eps];
    
    bool cmp(seg a, seg b){
        return a.h < b.h;
    }
    
    struct node
    {
        int l, r, sum;
        double len1, len2;
    }pre[eps<<2];
    
    void build(int l, int r, int k){
        pre[k].l = l;
        pre[k].r = r;
        pre[k].sum = pre[k].len1 = pre[k].len2 = 0;
    
        if (l == r) return;
        int m = (l+r)>>1;
        build(l, m, k<<1);
        build(m+1, r, k<<1|1);
    }
    
    void down(int k){
        if (pre[k].sum) pre[k].len1 = x[pre[k].r+1] - x[pre[k].l]; 
        else if (pre[k].l == pre[k].r) pre[k].len1 = 0;
        else pre[k].len1 = pre[k<<1].len1 + pre[k<<1|1].len1;
        
        // 区别于矩形面积并得地方,多有一个检测是否有被覆盖两次的边 
        // 要注意这几个 if else 的顺序 ,顺序不一样就会错哦 , 可以想想为什么
        if (pre[k].sum >= 2) pre[k].len2 = pre[k].len1;
        else if (pre[k].l == pre[k].r) pre[k].len2 = 0; 
        else if (pre[k].sum == 1) pre[k].len2 = pre[k<<1].len1 + pre[k<<1|1].len1;
        else pre[k].len2 = pre[k<<1].len2 + pre[k<<1|1].len2;
    }
    
    void update(int l, int r, int k, int pt){
        if (l <= pre[k].l && pre[k].r <= r){
            pre[k].sum += pt;
            down(k);
            return;
        }
        int m = (pre[k].l + pre[k].r) >> 1;
        // 这个地方当时写完有一个BUG ,一顿找啊 我是,就是自己写线段树,习惯了 l , m , k<<1 这样的参数传递,实则不然
        if (l <= m) update(l, r, k<<1, pt);
        if (r > m) update(l, r, k<<1|1, pt);
        down(k);
    }
    
    int main() {
        int t, n;
        double a, b, c, d;
        
        cin >>t;
        while (t--){
            cin >> n;
            int k = 1;
            for(int i = 0; i < n; i++){
                scanf("%lf%lf%lf%lf", &a, &b, &c, &d);        
                po[k].l = po[k+1].l = a;
                po[k].r = po[k+1].r = c;
                po[k].h = b, po[k+1].h = d;
                po[k].f = 1, po[k+1].f = -1;
                x[k] = a, x[k+1] = c;
                k += 2;
            }
            sort(x+1, x+k);
            sort(po+1, po+k, cmp);
            int t = 2;
            for(int i = 2; i < k; i++){
                if (x[i] != x[i-1]) x[t++] = x[i];
            }
            build(1, t-1, 1);
            double ans = 0;
            for(int i = 1; i < k; i++){
                int l = lower_bound(x+1, x+t, po[i].l) - x;
                int r = lower_bound(x+1, x+t, po[i].r) - x - 1;
            
                update(l, r, 1, po[i].f);
                ans += pre[1].len2*(po[i+1].h - po[i].h);
            }
            printf("%.2f
    ", ans);
        }
    
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    Analysis Services features supported by SQL Server editions
    Azure DevOps to Azure AppServices
    Power BI For Competition
    Win10开机“提示语音”以及”随机播放音乐”
    Azure DevOps
    Allow Only Ajax Requests For An Action In ASP.NET Core
    Mobile CI/CD 101
    Configure SSL for SharePoint 2013
    AWS Step Function Serverless Applications
    Cordova Upload Images using File Transfer Plugin and .Net core WebAPI
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/7689902.html
Copyright © 2020-2023  润新知