zoukankan      html  css  js  c++  java
  • HDU-1828 Picture(扫描线)

    题目大意:给若干个矩形,求轮廓边长。

    题目分析:与求面积类似。按从下往上扫描,仍然是底边添加,上边删除。但要同时维护竖边的数目,每次扫描对答案的贡献为扫描线上总覆盖长度的变化量加上竖边的增量。总覆盖长度的变化为正说明下轮廓增加,为负以为着碰到了上轮廓增加。

    代码如下:

    # include<bits/stdc++.h>
    using namespace std;
    # define mid (l+(r-l)/2)
    # define LL long long
    
    const int N=5000;
    
    struct Segment
    {
    	int x1,x2,y;
    	int d;
    };
    struct Node
    {
    	int cnt;	///覆盖的竖线数目
    	int len;	///被覆盖总长度
    	int time;	///被覆盖覆盖的次数
    	bool cl,cr;	///左右端点是否被覆盖
    };
    Segment seg[N<<1];
    Node nde[(N<<4)+5];
    
    bool comp(Segment &s1,Segment &s2)
    {
    	return s1.y<s2.y;
    }
    
    void build(int rt,int l,int r)
    {
    	nde[rt].cnt=0;
        nde[rt].len=0;
    	nde[rt].time=0;
    	nde[rt].cl=nde[rt].cr=false;
    	if(l==r) return ;
    	build(rt<<1,l,mid);
    	build(rt<<1|1,mid+1,r);
    }
    
    void pushUp(int rt,int l,int r)
    {
    	if(nde[rt].time>0){
    		nde[rt].cl=nde[rt].cr=true;
    		nde[rt].cnt=2;
    		nde[rt].len=r-l+1;
    	}else if(l==r){
    		nde[rt].cl=nde[rt].cr=false;
    		nde[rt].cnt=0;
    		nde[rt].len=0;
    	}else{
    		nde[rt].cl=nde[rt<<1].cl;
    		nde[rt].cr=nde[rt<<1|1].cr;
    		nde[rt].len=nde[rt<<1].len+nde[rt<<1|1].len;
    		nde[rt].cnt=nde[rt<<1].cnt+nde[rt<<1|1].cnt;
    		if(nde[rt<<1].cr&&nde[rt<<1|1].cl)
    			nde[rt].cnt-=2;
    	}
    }
    
    void update(int rt,int l,int r,int L,int R,int d)
    {
    	if(L<=l&&r<=R){
    		nde[rt].time+=d;
    		pushUp(rt,l,r);
    	}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,l,r);
    	}
    }
    
    int main()
    {
    	int n;
    	while(~scanf("%d",&n))
    	{
    		int L=10000,R=-10000;
    		int x1,y1,x2,y2;
    		for(int i=0;i<n;++i){
    			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    			seg[i<<1].x1=seg[i<<1|1].x1=x1,seg[i<<1].y=y1;
    			seg[i<<1].x2=seg[i<<1|1].x2=x2,seg[i<<1|1].y=y2;
    			seg[i<<1].d=1;
    			seg[i<<1|1].d=-1;
    			L=min(x1,L);
    			R=max(x2,R);
    		}
    		n<<=1;
    		build(1,L,R-1);
    		sort(seg,seg+n,comp);
    		int ans=0;
    		int last=0;
    		seg[n].y=seg[n-1].y;
    		for(int i=0;i<n;++i){
    			update(1,L,R-1,seg[i].x1,seg[i].x2-1,seg[i].d);
    			ans+=nde[1].cnt*(seg[i+1].y-seg[i].y);
    			ans+=abs(nde[1].len-last);
    			last=nde[1].len;
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    百度地图API(二)
    Android开发--页面切换
    Android开发--Socket通信
    android开发--okhttp
    android开发--下载图片
    Android--Handler
    android开发--多线程
    android开发--Application
    android开发--ormlite
    android开发--数据库(更新或者降低版本)
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5748485.html
Copyright © 2011-2022 走看看