zoukankan      html  css  js  c++  java
  • POJ1177 Picture 线段树+离散化+扫描线

    求最终的覆盖图形周长,写这种代码应该短而精确,差的比较远

    /*
    Problem: 1177        User: 96655
    Memory: 348K        Time: 32MS
    Language: C++        Result: Accepted
    */
    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include <algorithm>
    using namespace std;
    const int maxn=10010;
    struct Node
    {
        int s,t,num,len,cover;
        bool lb,rb;
        void change(int o)
        {
            cover+=o;
            if(cover==0)len=lb=rb=num=0;
            else len=t-s,lb=1,rb=1,num=1;
        }
    } node[maxn<<2];
    struct Line
    {
        int x,y1,y2,flag;
        void fun(int a,int b,int c,int d)
        {
            x=a,y1=b,y2=c,flag=d;
        }
        bool operator<(const Line &e)const
        {
            if(x==e.x)
                return flag>e.flag;
            return x<e.x;
        }
    } line[maxn];
    int y[maxn];
    void build(int rt,int l,int r)
    {
        node[rt].s=y[l];
        node[rt].t=y[r];
        node[rt].num=node[rt].len=node[rt].cover=0;
    
        if(l+1==r)return;
        int m=(l+r)>>1;
        build(rt*2,l,m);
        build(rt*2+1,m,r);
    }
    void update_line(int rt)
    {
        node[rt].lb=node[rt*2].lb;
        node[rt].rb=node[rt*2+1].rb;
        node[rt].num=node[rt*2].num+node[rt*2+1].num-node[rt*2].rb*node[rt*2+1].lb;
    }
    void update_len(int rt)
    {
        node[rt].len=node[rt*2].len+node[rt*2+1].len;
    }
    void update(int rt,int l,int r,Line e)
    {
        if(l+1==r)
        {
            node[rt].change(e.flag);
            return;
        }
        int m=(l+r)>>1;
        if(e.y1<node[rt*2].t)update(rt*2,l,m,e);
        if(e.y2>node[rt*2+1].s)update(rt*2+1,m,r,e);
        update_len(rt);
        update_line(rt);
    }
    int main()
    {
        int n,x1,x2,y1,y2,cnt=0,d=1;
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            line[++cnt].fun(x1,y1,y2,1);
            y[cnt]=y1;
            line[++cnt].fun(x2,y1,y2,-1);
            y[cnt]=y2;
        }
        sort(y+1,y+1+cnt);
        sort(line+1,line+1+cnt);
        for(int i=2; i<=cnt; ++i)
            if(y[i]!=y[i-1])y[++d]=y[i];
        build(1,1,d);
        int perimeter=0;
        int now_len=0;
        int now_num=0;
        for(int i=1; i<=cnt; ++i)
        {
            update(1,1,d,line[i]);
            if(i>1)perimeter+=2*now_num*(line[i].x-line[i-1].x);
            perimeter+=abs(node[1].len-now_len);
            now_num=node[1].num;
            now_len=node[1].len;
        }
        printf("%d
    ",perimeter);
        return 0;
    }
    View Code
  • 相关阅读:
    Spring基础知识点总结
    秒懂设计模式--代理模式(proxy)
    秒懂设计模式--工厂模式
    秒懂设计模式--适配器模式
    秒懂设计模式--装饰者模式
    秒懂设计模式--观察者模式
    单例模式的几种实现
    springboot2.0+spring cloud+eureka搭建微服务步骤
    字符串排序算法
    bitbucket的简单使用
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/4956291.html
Copyright © 2011-2022 走看看