zoukankan      html  css  js  c++  java
  • codevs 2995 楼房

    /*暴力30分*/
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<map>
    #define maxn 100010
    using namespace std;
    int n,l=0x7fffffff,r=-0x7fffffff;
    int s,ans1[maxn*5],ans2[maxn*5],h[maxn];
    struct node
    {
        int li,ri,hi;
    }p[maxn];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          {
              scanf("%d%d%d",&p[i].hi,&p[i].li,&p[i].ri);
              l=min(l,p[i].li);r=max(r,p[i].ri);
          }
        for(int i=1;i<=n;i++)
          for(int j=p[i].li;j<p[i].ri;j++)
            h[j]=max(h[j],p[i].hi);
        int pre=0;
        for(int i=l;i<=r;i++)
          {
              if(h[i]!=pre)
                {
                    ans1[++s]=i;
                    ans2[s]=pre;
                    ans1[++s]=i;
                    ans2[s]=h[i];
                    pre=h[i];
              }
          }
        printf("%d
    ",s);
        for(int i=1;i<=s;i++)
          printf("%d %d
    ",ans1[i],ans2[i]);
        return 0;
    }
    /*神奇的set+sort*/
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<set>
    #define maxn 200010
    using namespace std;
    multiset<int,greater<int> >s;
    int n,tot,t,ans1[maxn*5],ans2[maxn*5];
    struct node
    {
        int x,k,b,h;
    }q[maxn];
    int cmp(const node &q1,const node &q2)//关键的cmp 
    {
        if(q1.x!=q2.x)return q1.x<q2.x;
        if(q1.k!=q2.k)return q1.k<q2.k;//挨在一起的 先考虑左 后考虑右 就不会把这里的4个点输出 
        if(q1.k==1)return q1.h>q2.h;//左边 先考虑高的 把低的覆盖了  
        if(q1.k==2)return q1.h<q2.h;//同理 
    }
    int main()
    {
        scanf("%d",&n);
        int l,r,hi;
        for(int i=1;i<=n;i++)
          {
              scanf("%d%d%d",&hi,&l,&r);
              q[++tot].x=l;q[tot].b=i;q[tot].k=1;q[tot].h=hi;
              q[++tot].x=r;q[tot].b=i;q[tot].k=2;q[tot].h=hi;
          }
        sort(q+1,q+1+tot,cmp);
        for(int i=1;i<=tot;i++)
          {
            if(q[i].k==1)
              {
                if(*s.begin()>=q[i].h)s.insert(q[i].h);
                else
                  {
                      t+=1;
                      ans1[t]=q[i].x;ans2[t]=*s.begin();
                      t+=1;
                      ans1[t]=q[i].x;ans2[t]=q[i].h;
                      s.insert(q[i].h);
                  }
              }
            if(q[i].k==2)
              {
                  if(*s.begin()==q[i].h&&s.count(q[i].h)==1)
                    {
                        s.erase(s.find(q[i].h));
                        t+=1;
                        ans1[t]=q[i].x;ans2[t]=q[i].h;
                        t+=1;
                      ans1[t]=q[i].x;ans2[t]=*s.begin();
                  }
                else s.erase(s.find(q[i].h));
              }
          }
        printf("%d
    ",t);
        for(int i=1;i<=t;i++)
          printf("%d %d
    ",ans1[i],ans2[i]);
        return 0;
    }
    /*
    离散化然后线段树维护每个点的hmax
    然后按照打爆力的方法找 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 100010
    using namespace std;
    int n,m,num,tot,a[maxn*2],b[maxn*2];
    int ans1[maxn*5],ans2[maxn*5],cnt;
    struct node
    {
        int l,r,h;
    }p[maxn];
    struct tree
    {
        int l,r,lc,rc,ans,lazy;
    }t[maxn*4];
    int cmp(const node &x,const node &y)
    {
        return x.h<y.h;
    }
    void Build(int li,int ri)
    {
        int k=++tot;
        t[k].l=li;t[k].r=ri;
        if(li!=ri-1)
          {
              t[k].lc=tot+1;Build(li,(li+ri)/2);
              t[k].rc=tot+1;Build((li+ri)/2,ri);
              t[k].ans=max(t[t[k].lc].ans,t[t[k].rc].ans);
          }
        else t[k].ans=0;
    }
    void updata(int k)
    {
        t[t[k].lc].ans=max(t[t[k].lc].ans,t[k].lazy);
        t[t[k].rc].ans=max(t[t[k].rc].ans,t[k].lazy);
        t[t[k].lc].lazy=max(t[t[k].lc].lazy,t[k].lazy);
        t[t[k].rc].lazy=max(t[t[k].rc].lazy,t[k].lazy);
        t[k].lazy=0;
    }
    void Change(int k,int li,int ri,int data)
    {
        if(li<=t[k].l&&ri>=t[k].r)
          {
              t[k].ans=max(data,t[k].ans);
              t[k].lazy=max(t[k].lazy,data);
              return;
          }
        if(t[k].lazy)updata(k);
        int mid=(t[k].l+t[k].r)/2;
        if(li<mid)Change(t[k].lc,li,ri,data);
        if(ri>mid)Change(t[k].rc,li,ri,data);
        t[k].ans=max(t[t[k].lc].ans,t[t[k].rc].ans);
    }
    int Query(int k,int p)
    {
        if(t[k].l==t[k].r-1)return t[k].ans;
        if(t[k].lazy)updata(k);
        int mid=(t[k].l+t[k].r)/2;
        if(p<mid)return Query(t[k].lc,p);
        else return Query(t[k].rc,p);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          {
              scanf("%d%d%d",&p[i].h,&p[i].l,&p[i].r);
              a[++m]=p[i].l;a[++m]=p[i].r;
          }
        sort(a+1,a+m+1);sort(p+1,p+1+n,cmp);
        b[++num]=a[1];
        for(int i=2;i<=m;i++)
          if(a[i]!=a[i-1])b[++num]=a[i];
        Build(1,m+1);
        for(int i=1;i<=n;i++)
          {
              int p1=lower_bound(b+1,b+1+num,p[i].l)-b;
              int p2=lower_bound(b+1,b+1+num,p[i].r)-b;
              Change(1,p1,p2,p[i].h);
          }
        for(int i=1;i<=num;i++)
          {
              ans1[i]=b[i];ans2[i]=Query(1,i);
              if(ans2[i]!=ans2[i-1])cnt++;
          }
        printf("%d
    ",cnt*2);
        for(int i=1;i<=num;i++)
          if(ans2[i]!=ans2[i-1])
            {
              printf("%d %d
    ",ans1[i],ans2[i-1]);
              printf("%d %d
    ",ans1[i],ans2[i]);
            }
        return 0;
    }
  • 相关阅读:
    图数据库-Neo4j使用
    [原创]networkx 画中文节点
    python networkx:绘制网络图
    Python二维数组,坑苦了
    xgboost
    python 机器学习
    计算机网络知识
    前端优化不完全指南(转)
    FlashFXP 4.3.1 注册码
    你真的会使用Chrome开发者工具吗?
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5734592.html
Copyright © 2011-2022 走看看