zoukankan      html  css  js  c++  java
  • HDU

    https://cn.vjudge.net/problem/HDU-1255

    题意

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

    分析

    求面积并的题:https://www.cnblogs.com/fht-litost/p/9580330.html

    这题求面积交,也就是cover>=2才计算,采用第一种方法就只用小小改动。

    以下用了第二种方法。这里得维护覆盖一次以上的长度,和覆盖两次以上的长度。重点在cal()函数。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <cmath>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <stack>
    #include <set>
    #include <bitset>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define ms(a, b) memset(a, b, sizeof(a))
    #define pb push_back
    #define mp make_pair
    #define pii pair<int, int>
    #define eps 0.0000000001
    #define IOS ios::sync_with_stdio(0);cin.tie(0);
    #define random(a, b) rand()*rand()%(b-a+1)+a
    #define pi acos(-1)
    const ll INF = 0x3f3f3f3f3f3f3f3fll;
    const int inf = 0x3f3f3f3f;
    const int maxn = 20000 + 10;
    const int maxm = 200000 + 10;
    const int mod = 10007;
    
    int n;
    double y[maxn];
    struct LINE{
        double x;
        double y1,y2;
        int flag;
        bool operator <(const LINE &a)const{
            return x<a.x;
        }
    }line[maxn];
    struct ND{
        double l,r;
        int cover;
        bool f;
        double one;//覆盖一次以上的长度
        double more;//覆盖两次以上的长度
    }tree[maxn<<2];
    void build(int rt,int l,int r){
        tree[rt].l=y[l];
        tree[rt].r=y[r];
        tree[rt].cover=0;
        tree[rt].one=tree[rt].more=0;
        tree[rt].f=false;
        if(l+1==r){
            tree[rt].f=true;
            return;
        }
        int mid = (l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid,r);
    }
    
    void cal(int rt){
        if(tree[rt].cover>=2){
            tree[rt].more=tree[rt].one=tree[rt].r-tree[rt].l;
        }else if(tree[rt].cover==1){
            tree[rt].one=tree[rt].r-tree[rt].l;
            if(tree[rt].f) tree[rt].more=0;
            else tree[rt].more=tree[rt<<1].one+tree[rt<<1|1].one;
        }else{
            if(tree[rt].f){
                tree[rt].more=tree[rt].one=0;
            }else{
                tree[rt].one=tree[rt<<1].one+tree[rt<<1|1].one;
                tree[rt].more=tree[rt<<1].more+tree[rt<<1|1].more;
            }
        }
    }
    void update(int rt,double l,double r,int flag){
        if(l==tree[rt].l&&r==tree[rt].r){
            tree[rt].cover+=flag;
            cal(rt);
            return;
        }
        if(tree[rt<<1].r>=r) update(rt<<1,l,r,flag);
        else if(l>=tree[rt<<1|1].l) update(rt<<1|1,l,r,flag);
        else{
            update(rt<<1,l,tree[rt<<1].r,flag);
            update(rt<<1|1,tree[rt<<1|1].l,r,flag);
        }
        cal(rt);
    }
    int main() {
    #ifdef LOCAL
        freopen("in.txt", "r", stdin);
    //    freopen("output.txt", "w", stdout);
    #endif
        int T,cas=1;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            int cnt=-1;
            double x1,x2,y1,y2;
            for(int i=0;i<n;i++){
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                y[++cnt]=y1;
                line[cnt].x=x1;
                line[cnt].y1=y1;
                line[cnt].y2=y2;
                line[cnt].flag=1;
                y[++cnt]=y2;
                line[cnt].x=x2;
                line[cnt].y1=y1;
                line[cnt].y2=y2;
                line[cnt].flag=-1;
            }
            sort(y,y+1+cnt);
            sort(line,line+1+cnt);
            build(1,0,cnt);
            update(1,line[0].y1,line[0].y2,line[0].flag);
            double area=0;
            for(int i=1;i<=cnt;i++){
                area+=tree[1].more*(line[i].x-line[i-1].x);
                update(1,line[i].y1,line[i].y2,line[i].flag);
            }
            printf("%.2f
    ",area);
        }
        return 0;
    }
  • 相关阅读:
    面向对象三大特性之多态
    作业
    面向对象三大特性之封装
    面向对象三大特性之继承
    面向对象(一)
    subprocess, re模块,logging, 包等使用方法
    模块二之序列化模块以及collections模块
    常用模块
    内置函数补充,函数递归,模块
    生成器以及面向过程编程
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9580444.html
Copyright © 2011-2022 走看看