• 楼房


    题目描述

    地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i])。地平线高度为0。在轮廓线长度最小的前提下,从左到右输出轮廓线。

    下图为样例2。

    输入输出格式

    输入格式:

    第一行一个整数n,表示矩形个数

    以下n行,每行3个整数h[i],l[i],r[i]表示第i个矩形。

    输出格式:

    第一行一个整数m,表示节点个数

    以下m行,每行一个坐标表示轮廓线上的节点。从左到右遍历轮廓线并顺序输出节点。第一个和最后一个节点的y坐标必然为0。

    输入输出样例

    输入样例#1:
    【样例输入1】
    2
    3 0 2
    4 1 3
    
    【样例输入2】
    5
    3 -3 0
    2 -1 1
    4 2 4
    2 3 7
    3 6 8
    
    输出样例#1:
    【样例输出1】
    6
    0 0
    0 3
    1 3
    1 4
    3 4
    3 0
    
    【样例输出2】
    14
    -3 0
    -3 3
    0 3
    0 2
    1 2
    1 0
    2 0
    2 4
    4 4
    4 2
    6 2
    6 3
    8 3
    8 0
    
    

    说明

    【数据范围】

    对于30%的数据,n<=100

    对于另外30%的数据,n<=100000,1<=h[i],l[i],r[i]<=1000

    对于100%的数据,1<=n<=100000,1<=h[i]<=10^9,-10^9<=l[i]<r[i]<=10^9

    思路

    参见 楼房 洛谷1382 && codevs2995 by:Soda 顺膜.

    有一个叫扫描线的东西,我没用到~

    有一种线段树的做法,我不会~

    然后就用堆模拟,手生的直接敲不对。。。

    代码实现

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=3e6;
     5 int n,s,lat,net,idd;
     6 int a,b,c;
     7 bool v[maxn];
     8 struct nate{int num,id,h;}f[maxn];
     9 bool cmp(const nate&x,const nate&y){return x.id<y.id;}
    10 int top;
    11 int h[maxn];
    12 void add(int x){
    13     h[++top]=x,a=top,b=a>>1;
    14     while(f[h[a]].h>f[h[b]].h&&b){
    15         h[a]^=h[b],h[b]^=h[a],h[a]^=h[b];
    16         a=b,b=a>>1;
    17     }
    18 }
    19 void dle(){
    20     a=1,b=a<<1,c=b|1;
    21     h[a]=h[top],h[top--]=0;
    22     while(1){
    23         if(f[h[c]].h>f[h[b]].h) b=c;
    24         if(f[h[b]].h>f[h[a]].h) h[a]^=h[b],h[b]^=h[a],h[a]^=h[b];
    25         else break;
    26         a=b,b=a<<1,c=b|1;
    27     }
    28 }
    29 int anss,ans[2][maxn];
    30 int main(){
    31     scanf("%d",&n);
    32     for(int i=1;i<=n;i++){
    33         scanf("%d%d%d",&a,&b,&c);
    34         f[++s]=(nate){i,b,a};
    35         f[++s]=(nate){i,c,a};
    36     }
    37     sort(f+1,f+s+1,cmp);
    38     for(int i=1;i<=s;){
    39         lat=f[h[1]].h;
    40         idd=f[i].id;
    41         while(idd==f[i].id){
    42             v[f[i].num]^=1;
    43             if(v[f[i].num]) add(i);
    44             else while(!v[f[h[1]].num]&&h[1]) dle();
    45             i++;
    46         }
    47         net=f[h[1]].h;
    48         if(lat==net) continue;
    49         ans[0][anss]=idd,ans[1][anss++]=lat;
    50         ans[0][anss]=idd,ans[1][anss++]=net;
    51     }
    52     printf("%d
    ",anss);
    53     for(int i=0;i<anss;i++)
    54     printf("%d %d
    ",ans[0][i],ans[1][i]);
    55     return 0;
    56 }
  • 相关阅读:
    NanUI for Winform发布,让Winform界面设计拥有无限可能
    新浪微博.Net SDK第三版源代码和示例【最后一次更新了】
    写个C#命令行参数解析的小工具
    Mac安装Windows 10的简明教程
    自己动手,让Entity Framework Power Tools在VS2015重放光彩
    C++CLI使用.net委托,*Callback注意"this"
    【转】IIS上的反向代理
    asp.net mvc 验证码
    win2008R2 下解决关于mysql odbc无法正常工作问题
    中国健康医学教育网
  • 原文地址:https://www.cnblogs.com/J-william/p/7162305.html
Copyright © 2020-2023  润新知