zoukankan      html  css  js  c++  java
  • HDU-1255 覆盖的面积 (扫描线)

    题目大意:给若干个矩形,统计重叠次数不为0的面积。

    题目分析:维护扫描线的长度时,只需要只统计覆盖次数大于1的区间即可。这是个区间更新,不过不能使用懒标记,但是数据规模不大,不用懒惰标记仍可以AC。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<map>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define mid (l+(r-l)/2)
    
    const int N=1000;
    
    void read(int &x)
    {
        x=0;
        char c;
        while((c=getchar())&&(c<'0'||c>'9'));
        x=c-'0';
        while(c=getchar()){
            if(c<'0'||c>'9') break;
            x=x*10+c-'0';
        }
    }
    
    //*****************************************
    
    struct Node
    {
        int c;
        double len;
    };
    struct Segment
    {
        double x1,x2,y;
        int d;
    };
    Segment seg[N*2+5];
    map<double,int>mp;
    vector<double>v;
    Node tr[(N<<3)+5];
    
    bool comp(const Segment &s1,const Segment &s2)
    {
        return s1.y<s2.y;
    }
    
    void pushUp(int rt)
    {
    	tr[rt].len=tr[rt<<1].len+tr[rt<<1|1].len;
    }
    
    void build(int rt,int l,int r)
    {
        tr[rt].c=0;
        tr[rt].len=0.0;
        if(l==r) return ;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
    }
    
    void update(int rt,int l,int r,int L,int R,int d)
    {
        if(l==r){
    		tr[rt].c+=d;
    		if(tr[rt].c>1) tr[rt].len=v[r]-v[l-1];
    		else tr[rt].len=0;
    	}else{
    		if(L<=mid) update(rt<<1,l,mid,L,R,d);
    		if(R>mid) update(rt<<1|1,mid+1,r,L,R,d);
    		pushUp(rt);
    	}
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T,n;
        read(T);
        while(T--)
        {
            read(n);
            v.clear();
            mp.clear();
            double x1,x2,y1,y2;
            for(int i=0;i<n;++i){
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                seg[i<<1].x1=seg[i<<1|1].x1=x1;
                seg[i<<1].x2=seg[i<<1|1].x2=x2;
                seg[i<<1].y=y1,seg[i<<1|1].y=y2;
                seg[i<<1].d=1,seg[i<<1|1].d=-1;
                v.push_back(x1);
                v.push_back(x2);
            }
            n<<=1;
            sort(seg,seg+n,comp);
            sort(v.begin(),v.end());
            int m=unique(v.begin(),v.end())-v.begin();
            for(int i=0;i<m;++i) mp[v[i]]=i+1;
    		
            seg[n].y=seg[n-1].y;
            build(1,1,m-1);
            double ans=0.0;
            for(int i=0;i<n;++i){
                update(1,1,m-1,mp[seg[i].x1],mp[seg[i].x2]-1,seg[i].d);
                ans+=tr[1].len*(seg[i+1].y-seg[i].y);
    			//cout<<tr[1].len<<endl;
            }
            printf("%.2lf
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    【转载】中文分词整理
    【转载】浅谈事件冒泡与事件捕获
    【转载】SpringCloud-Eurek 心跳阈值说明
    【转载】Linux下查看CPU、内存占用率
    Linux内存、性能诊断中vmstat命令的详解
    【转载】springboot四 全局异常处理
    【转载】linux系统时间自动同步:ntp
    springboot整合三 共享session,集成springsession
    git把一个分支上的某个提交合并到另一个分支
    VS Code打开新的文件会覆盖窗口中的,怎么改
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5750126.html
Copyright © 2011-2022 走看看