• POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算


    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度。

    我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可。因为最后的轮廓必定是由不重合的线段长度组成的,这样理论上是对的

    要注意处理高度相同的线段,把底边优先处理(在代码里就是f标记为1的线段),因为若是一个矩形的底边和另一个矩形的上边重合,则这个轮廓肯定不能算

    不过POJ和HDU的数据好像都比较弱,我没进行上面的细节处理也AC了,不过一个很简单的数据就会不对,所以还是要处理一下才是真正正确的代码

    我之前敲代码的时候还想起在线段树里面的覆盖要涉及懒惰标记(因为是对区间进行覆盖嘛,没向子走)和向上更新。。。不过想了一下不用,这个线段树不是普通那种,因为总是先覆盖底边,然后由等长的上边来解除覆盖,所以区间总是相对不变的,没必要进行向上或者向下更新

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid,r
    using namespace std;
    const int N=10010;
    struct node
    {
        int lx,ly,hx,hy;
    }rec[N];
    struct node2
    {
        int l,r,h,f;
        bool operator <(const node2& rhs) const{
            if (h==rhs.h){
                return f>rhs.f;
            }
            else return h<rhs.h;
        }
    }seg[N*2];
    int X[N*2];
    int n;
    int flag[N<<2];
    int d[N<<2];
    void build(int rt,int l,int r)
    {
        flag[rt]=0;
        d[rt]=0;
        if (r-l<=1) return;
        int mid=(l+r)>>1;
        build(lson);
        build(rson);
    }
    void up(int rt,int l,int r)
    {
        if (flag[rt]>0){
            d[rt]=X[r]-X[l];
        }
        else
        {
            if (r-l<=1) d[rt]=0;
            else d[rt]=d[rt<<1]+d[rt<<1|1];
        }
    }
    void cover(int L,int R,int v,int rt,int l,int r)
    {
        if (L<=l && r<=R)
        {
            flag[rt]+=v;
            up(rt,l,r);
            return;
        }
        if (r-l<=1) return ;
        int mid=(l+r)>>1;
        if (R<=mid) cover(L,R,v,lson);
        else
        if (L>mid)  cover(L,R,v,rson);
        else
        {
            cover(L,R,v,lson);
            cover(L,R,v,rson);
        }
        up(rt,l,r);
    }
    int main()
    {
        while (scanf("%d",&n)!=EOF)
        {
            int cnt=0;
            for (int i=0;i<n;i++){
                scanf("%d%d%d%d",&rec[i].lx,&rec[i].ly,&rec[i].hx,&rec[i].hy);
                X[++cnt]=rec[i].lx;
                seg[cnt].l=rec[i].lx;
                seg[cnt].r=rec[i].hx;
                seg[cnt].h=rec[i].ly;
                seg[cnt].f=1;
    
                X[++cnt]=rec[i].hx;
                seg[cnt].l=rec[i].lx;
                seg[cnt].r=rec[i].hx;
                seg[cnt].h=rec[i].hy;
                seg[cnt].f=-1;
            }
            int m=1;
            sort(X+1,X+1+cnt);
            sort(seg+1,seg+1+cnt);
            for(int i=2;i<=cnt;i++){
                if (X[i]!=X[i-1]){
                    X[++m]=X[i];
                }
            }
            int ans=0;
            build(1,1,m);
            //for (int i=1;i<=m;i++) cout<<X[i]<<endl;
            for (int i=1;i<=cnt;i++){
                //cout<<seg[i].l<<" "<<seg[i].r<<" "<<seg[i].f<<endl;
                int l=lower_bound(X+1,X+1+m,seg[i].l)-X;
                int r=lower_bound(X+1,X+1+m,seg[i].r)-X;
                int tmp=d[1];
                //cout<<X[l]<<" xxx "<<X[r]<<endl;
               // cout<<"bf: "<<d[1]<<endl;
                cover(l,r,seg[i].f,1,1,m);
                tmp=d[1]-tmp;
                if (tmp<0) tmp=-tmp;
                //cout<<"af: "<<d[1]<<endl;
                //cout<<tmp<<endl;
                ans+=tmp;
            }
            //cout<<ans<<endl;
            cnt=0;
            for (int i=0;i<n;i++){
                X[++cnt]=rec[i].ly;
                seg[cnt].l=rec[i].ly;
                seg[cnt].r=rec[i].hy;
                seg[cnt].h=rec[i].lx;
                seg[cnt].f=1;
    
                X[++cnt]=rec[i].hy;
                seg[cnt].l=rec[i].ly;
                seg[cnt].r=rec[i].hy;
                seg[cnt].h=rec[i].hx;
                seg[cnt].f=-1;
            }
            sort(X+1,X+1+cnt);
            sort(seg+1,seg+1+cnt);
            m=1;
            for (int i=2;i<=cnt;i++){
                if (X[i]!=X[i-1]){
                    X[++m]=X[i];
                }
            }
            build(1,1,m);
            for (int i=1;i<=cnt;i++){
                int l=lower_bound(X+1,X+1+m,seg[i].l)-X;
                int r=lower_bound(X+1,X+1+m,seg[i].r)-X;
                int tmp=d[1];
                cover(l,r,seg[i].f,1,1,m);
                tmp=d[1]-tmp;
                if (tmp<0) tmp=-tmp;
                ans+=tmp;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    /*
    2
    0 0 5 2
    2 -2 4 3
    */
    

      

  • 相关阅读:
    asp.net mvc 三层加EF两表联查
    asp.net mvc 三层加EF 登录注册 增删改查
    超市管理系统
    asp.net三层架构增删改查
    ACCP8.0 HTML标签
    Sql 优化解决方案
    抽象类与抽象方法
    Form 表单提交的几种方式
    C# 接口的使用(工厂模式)
    使用VBA设置打印页面高度和宽度
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3872958.html
Copyright © 2020-2023  润新知