zoukankan      html  css  js  c++  java
  • Atlantis HDU

    给出一堆矩形的左下右上坐标,问矩形面积并

    扫描线的本质就是把图形分层,每层的边界就是一条“扫描线”

    这里的做法是把图形按照y坐标分成一条条等高的长条,

    让长条不断加入我们的图形,即扫描的过程

    {

    对于每一个长条,它对图形的影响取决于它的长度,它的高度还有它是组合图的入边还是出边(取决于我们扫的方向,这里从下往上扫)

    那么我们维护的信息就是这个时间点,x轴上被覆盖的总面积,

    这个数据的维护用到了线段树,

    首先离散化x轴上所有出现的坐标

    如果这个扫描线是入边,那么对应区间的【完全覆盖次数】+1,反之-1,这是区间修改

    pushup过程中,

    1如果这个节点被完全覆盖,那么向上传递这个区间的长度,

    2否则如果是叶子节点,上传0;

    3否则向上传递子节点覆盖的总长度,这里注意,整个过程中不需要pushdown操作,所以我们把1,3分成两种情况

    }

    这条扫描线的信息更新完毕,我们就需要把这条扫描线到下一条扫描线的距离×总区间覆盖长度的值加进最后的答案

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    const int maxn=210;
    
    struct Node{
        double l,r,h;
        int d;
        Node(){};
        Node(double a,double b,double c,int d):l(a),r(b),h(c),d(d){}
        bool operator<(const Node &b)const{
            return h<b.h;
        }
    }node[maxn];
    
    struct st{
        int cover;
        double sum;
    }ST[maxn<<2];
    
    double X[maxn];
    
    void pushup(int l,int r,int rt){
        if(ST[rt].cover)ST[rt].sum=X[r+1]-X[l];
        else if(l==r)ST[rt].sum=0;
        else ST[rt].sum=ST[rt<<1].sum+ST[rt<<1|1].sum;
    }
    void build(int l,int r,int rt){
        if(l==r){
            ST[rt].cover=0;
            ST[rt].sum=0;
            return;
        }
        int m=(l+r)>>1;
        build(l,m,rt<<1);
        build(m+1,r,rt<<1|1);
        pushup(l,r,rt);
    }
    void update(int a,int b,int c,int l,int r,int rt){
        if(a<=l&&b>=r){
            ST[rt].cover+=c;
            pushup(l,r,rt);
            return;
        }
        int m=(l+r)>>1;
        if(a<=m)update(a,b,c,l,m,rt<<1);
        if(b>m)update(a,b,c,m+1,r,rt<<1|1);
        pushup(l,r,rt);
    }
    
    int main(){
        int n;
        int kase=0;
        while(~scanf("%d",&n)&&n){
            memset(node,0,sizeof(node));
            memset(ST,0,sizeof(ST));
            int tot=0;
            for(int i=1;i<=n;i++){
                double x1,y1,x2,y2;
                scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
                X[++tot]=x1;
                node[tot]=Node(x1,x2,y1,1);
                X[++tot]=x2;
                node[tot]=Node(x1,x2,y2,-1);
            }          
            sort(X+1,X+tot+1);
    
            sort(node+1,node+tot+1);
    
            int k=1;
            for(int i=2;i<=tot;i++){
                if(X[i]!=X[i-1]){
                    X[++k]=X[i];
                }
            }
            build(1,k-1,1);
            double ans=0;
            
            for(int i=1;i<tot;i++){
                int l=lower_bound(X+1,X+1+k,node[i].l)-X;
                int r=lower_bound(X+1,X+1+k,node[i].r)-X-1;
    
                update(l,r,node[i].d,1,k-1,1);
    
                ans+=ST[1].sum*(node[i+1].h-node[i].h);
            }
            printf("Test case #%d
    Total explored area: %.2lf
    
    ",++kase,ans);
        }
    }

    吐槽一句,省赛真的太遗憾了,要是把题目分配优化一下结果就会好得多,

    “至少你要敲一下啊”,赛后学长们是这么讲的,

    没有快速打出代码的自信,我也就放过了猜出的正解,

    打出代码,才有一交的机会,在最后一刻交一发,哪怕wa起码不会留下遗憾

    保持冷静地快速敲出代码,这就是我接下来训练的目标吧

  • 相关阅读:
    C#经典书籍推荐 [转]
    ubuntu的ADSL拨号上网(主要是无线网情况下) [转]
    2007元旦粤北山区:我的“多背1公斤”
    Javascript中给动态生成的表格添加样式,JavaScript里setAttribute的问题
    Asp.net2.0的AjaxPro中不能使用Server.HtmlEncode()函数?
    去了深圳出差,到了珠海泡温泉
    2007元旦粤北山区:翻山越岭到乳源,半途而废云门寺,风雨兼程向瑶山
    很好很强大的FLEX控件
    PHP生成PDF文档的FPDF类
    Flex,事件,绑定,机制
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611326.html
Copyright © 2011-2022 走看看