• 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
  • 相关阅读:
    HDU 6071
    HDU 6073
    HDU 2124 Repair the Wall(贪心)
    HDU 2037 今年暑假不AC(贪心)
    HDU 1257 最少拦截系统(贪心)
    HDU 1789 Doing Homework again(贪心)
    HDU 1009 FatMouse' Trade(贪心)
    HDU 2216 Game III(BFS)
    HDU 1509 Windows Message Queue(队列)
    HDU 1081 To The Max(动态规划)
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/4956291.html
Copyright © 2020-2023  润新知