zoukankan      html  css  js  c++  java
  • 51nod 2488 矩形并的面积

    在二维平面上,给定两个矩形,满足矩形的每条边分别和坐标轴平行,求这个两个矩形的并的面积。即它们重叠在一起的总的面积。

     收起

    输入

    8个数,分别表示第一个矩形左下角坐标为(A,B),右上角坐标为(C,D);第二个矩形左下角坐标为(E,F),右上角坐标为(G,H)。
    保证A<C,B<D,E<G,F<H。
    保证所有数的绝对值不超过2*10^9,矩形并的面积≤2*10^9。

    输出

    输出一个数表示矩阵并的面积。

    输入样例

    -3 0 3 4 0 -1 9 2

    输出样例

    45

    得空再写题解,先贴个代码

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
     
    using namespace std;
    #define lson rt<<1
    #define rson rt<<1|1
    const int maxn = 2e2+10;
    int n;//矩形数
    int e,p;//边数和点数
    //边
    struct Edge{
        double l,r;//边的左右两点
        double h;//边的高度
        int tag;//边的标记,+1or-1,1代表下边,-1代表上边
    };
    Edge edge[maxn];
    //线段树
    struct SegTree{
        int l,r;//线段树
        int tag;//标记
        double len;//长度
    };
    SegTree st[maxn<<2];
    double x[maxn];//离散化之后的横坐标点
     
    inline void GetEdge( double l, double r, double h, int tag)
    {
        edge[e].l = l;
        edge[e].r = r;
        edge[e].h = h;
        edge[e].tag = tag;
        e++;
    }
     
    inline void GetPoint( double xi)
    {
        x[p++] = xi;
    }
     
    //按照高度从小到大排序
    bool cmp( Edge p, Edge q)
    {
        return p.h < q.h;
    }
     
    void Build( int l, int r, int rt)
    {
        st[rt].l = l;
        st[rt].r = r;
        st[rt].tag = st[rt].len = 0;
        if( l == r)
            return;
        int mid = (l+r)>>1;
        Build(l,mid,lson);
        Build(mid+1,r,rson);
        //本题不PushUp
    }
     
    void PushUp( int rt)
    {
        if( st[rt].tag)//tag>0,说明是下边,直接求出长度
            st[rt].len = x[st[rt].r+1]-x[st[rt].l];
        else if( st[rt].l == st[rt].r)//是个点,长度为0
            st[rt].len = 0;
        else//长度为儿子结点长度之和
            st[rt].len = st[lson].len+st[rson].len;
    }
     
    void Update( int L, int R, int rt, int tag)
    {
        if( L <= st[rt].l && R >= st[rt].r)
        {
            st[rt].tag += tag;
            PushUp(rt);
            return;
        }
        int mid = (st[rt].l+st[rt].r)>>1;
        if( R <= mid)
            Update(L,R,lson,tag);
        else if( L > mid)
            Update(L,R,rson,tag);
        else
        {
            Update(L,mid,lson,tag);
            Update(mid+1,R,rson,tag);
        }
        PushUp(rt);
    }
     
    int main()
    {
       
            e = 0;
            p = 0;
            double x1,y1,x2,y2;
            for( int i = 0; i < 2; i++)
            {
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                GetEdge(x1,x2,y1,1);//底边
                GetEdge(x1,x2,y2,-1);//定边
                GetPoint(x1);//左端点
                GetPoint(x2);//右端点
            }
            sort(edge,edge+e,cmp);
            sort(x,x+p);
     
            //点去重
            int tmp = p;
            p = 1;
            for( int i = 1; i < tmp; i++)
                if( x[i] != x[i-1])
                    x[p++] = x[i];
     
            //建树
            Build(0,p-1,1);
            double ans = 0;
            for( int i = 0; i < e-1; i++)
            {
                int l = lower_bound(x,x+p,edge[i].l)-x;
                int r = lower_bound(x,x+p,edge[i].r)-x-1;
                Update(l,r,1,edge[i].tag);
                ans += (edge[i+1].h-edge[i].h)*st[1].len;
            }
            printf("%.0f",ans);
     
     
        return 0;
    }
  • 相关阅读:
    POJ-1189 钉子和小球(动态规划)
    POJ-1191-棋盘分割(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
  • 原文地址:https://www.cnblogs.com/BlueDoor1999/p/13301384.html
Copyright © 2011-2022 走看看