zoukankan      html  css  js  c++  java
  • 解题报告 Figure of the city

     

    1.        题目  Figure of the city

    题目描述

        60 B.C.

    Latium省的Genoa是亚平宁半岛西海岸北端的一片土地,自然资源丰富,却无人居住。你受到罗马执政官Caesar的委任,前往Genoa建立新的城市。Caesar对这次任务的要求是在Genoa这片土地上建立起一座繁荣的城市,他将以此作为衡量你的表现的标准。

    正在你大刀阔斧地进行城市建设的时候,Caesar突然写信给你,说他要检查Genoa的建设情况。Caesar希望知道你的城市是什么样子,但是他又非常的忙,所以他只要你描述一下城市的轮廓就可以了,他将依照城市的轮廓决定你的薪水。

    怎样描述一个城市的轮廓呢?我们知道Genoa所有的建筑共享一个地面,你可以认为它是水平的。所有的建筑用一个三元组(Li,Hi,Ri)其中LiRi分别是建筑的左坐标和右坐标,Hi就是建筑的高度。在下方所示的图表中左边建筑物描述如下(1,11,5),(2,6,7),(3,13,9),(12,7,16),(14,3,25),(19,18,22),(23,13,29),(24,4,28),右边用轮廓线的顺序(1,11,3,13,9,0,12,7,16,3,19,18,22,3,23,13,29,0)表示:


     

    输入数据

        在输入数据中,你将得到一系列表示建筑的三元组。在输入数据中所有建筑的坐标中的数值都是小于10000的正整数,且至少有1幢建筑,最多有5,000幢建筑。在输入输入中每幢建筑的三元组各占一行。三元组中的所有整数应由一个或多个空格分开。

    输出数据

        在输出数据中,你被要求给出城市的轮廓线。你可以这样来描述:对于所有轮廓线上的折点,按顺序排好,第奇数个点输出x坐标,第偶数个点输出y坐标,两个数之间用空格分开。

    样例输入

    1 11 5

    2 6 7

    3 13 9

    12 7 16

    14 3 25

    19 18 22

    23 13 29

    24 4 28

     

    样例输出

    1 11 3 13 9 0 12 7 16 3 19 18 22 3 23 13 29 0

     

    2.        题目来源  又开始集训了

    3.        算法 

    这里主要介绍两种算法:浮水法、直接模拟。

     

    首先说一下直接模拟。这是 Leve 的解法。

    每次读入的时候,直接更新这一个点(在这个楼包括范围内的点)的最高的一个值,记录为这一个点的高度。边读边处理(当每读入一个楼的时候,枚举每一个在这个楼的范围内的点,如果没有这个楼高,则更新这个点),读完之后直接输出,注意输出的时候是输出横坐标还是纵坐标。

    其实这个题这么看才像是第一题。

     

    然后浮水法,是 Ray 想到的。

    上浮思想:设竖直平面中存在有一些高度不同的线段,当一个线段上方没有被其他线段挡着时,这个线段就可以上浮,如果一个线段(或是它的一部分)可以上浮到无限高,那么显然,这个线段(或这一部分)所在的高度是他所覆盖的这一个数轴范围内(将平面的无限低的地方看做有一个数轴)最高的。

    然后再看这个题,将图形的竖直的线段都扒掉,那么剩下的就是一些浮在空中的线段,所以可以用浮水法。(实际上一般的像这样的线段类问题都可以用浮水法)

    浮水法其实是一个递归的过程,首先,当一条线段满足上浮的条件时,让他上浮(用 while 循环控制),但是当他不满足上浮的条件时,将他被挡住的那一段切掉,然后接着递归的让他剩下的那部分上浮。

    一开始要用排序进行预处理。

    因为有高度为零的情况,所以可以一开始先在最底部画一条线段,使这一条线段的初始高度为零,这样应该为零的地方是上浮不起来的。

    4.        注意事项

    注意这一句话:

    对于所有轮廓线上的折点,按顺序排好,第奇数个点输出x坐标,第偶数个点输出y坐标,两个数之间用空格分开。

    那个输出,输出的不是每一个拐点的横坐标 & 纵坐标(这样还得进行特判,需要个一个点输出一个坐标,理论上讲也能输出数据,但是巨麻烦),而是横坐标 || 纵坐标。

    审题是关键。

    5.        时空复杂度

    直接模拟是 O(n)

    浮水法用到了递归,不好估计,不过放心,不会超时也不会爆栈。

    6.        程序代码

    模拟:Leve  Pascal

    var

     h:array[1..10000] of longint;

     x,y,i,hh,min,max:longint;

    begin

     assign(input,'input.txt');

     assign(output,'output.txt');

     reset(input);

     rewrite(output);

     min:=maxlongint;

     max:=0;

     while not eof do

       begin

         readln(x,hh,y);

            if x<min then min:=x;

            if y>max then max:=y;

            for i:=x to y-1 do

             if h[i]<hh then

              h[i]:=hh;

           end;

      i:=min;

      while i<=max do

       begin

        write(i,' ');

           write(h[i],' ');

           while (h[i+1]=h[i]) and (i<=max) do inc(i);

            inc(i);

       end;

     close(input);

     close(output);

    end.

     

     

    上浮:Ray Pascal

      var

        lb,al,la,i,n,m,minl,maxr:longint;

        f,l,r,h:array[0..10010] of longint;

        v:array[0..10010] of boolean;

      procedure doing(x,y,t:longint);

        begin

          if v[i] then exit;

          while (t>0)and((l[t-1]>y)or(r[t-1]<=x)) do dec(t);

          if t<=0 then

            begin

              f[x]:=h[i];

              exit;

            end;

          if l[t-1]>x then doing(x,l[t-1]-1,t-1);

          if r[t-1]<=y then doing(r[t-1],y,t-1);

        end;

      procedure qsort(ll,rr:longint);

        var

          i,j,x,y:longint;

        begin

          i:=ll;j:=rr;x:=h[(ll+rr)>>1];

          repeat

            while h[i]>x do inc(i);

            while x>h[j] do dec(j);

            if not(i>j) then

              begin

                y:=h[i];h[i]:=h[j];h[j]:=y;

                y:=l[i];l[i]:=l[j];l[j]:=y;

                y:=r[i];r[i]:=r[j];r[j]:=y;

                inc(i);dec(j);

              end;

          until(i>j);

          if i<rr then qsort(i,rr);

          if ll<j then qsort(ll,j);

        end;

      begin

        assign(input,'input.txt');

        reset(input);

        assign(output,'output.txt');

        rewrite(output);

        minl:=20000;

        maxr:=-1;

        fillchar(f,sizeof(f),255);

        while not eof do

          begin

            inc(m);

            readln(l[m],h[m],r[m]);

            if l[m]<minl then minl:=l[m];

            if r[m]>maxr then maxr:=r[m];

          end;

        qsort(1,m);

        inc(m);l[m]:=minl;r[m]:=maxr;h[m]:=0;

        f[l[1]]:=h[1];

        for i:=2 to m do

          begin

            doing(l[i],r[i],i);

            v[i]:=true;

          end;

        for i:=minl to maxr do

          if f[i]<>-1 then write(i,' ',f[i],' ');

        close(input);

        close(output);

      end.

    7.        囧囧的阿相:

    话说,受某 oj 上得某个 BT 的某道题(跌落的世界、立体图。。。神马的)的影响,本人一看到图形题就发虚,其实图形题不一定有多难。

  • 相关阅读:
    Python量化分析,计算KDJ
    Ubuntu16.04安装Python3.6 和pip(python3 各版本切换)
    使用docker加载已有镜像安装Hyperledger Fabric v1.1.0
    Ubuntu 16.04将左侧面板置于底部
    解决Flask局域网内访问不了的问题
    Ubuntu 16.04 安装Go 1.9.2
    Ubuntu16.04下安装Hyperledger Fabric 1.0.0
    Ubuntu 16.04安装Docker-CE
    用Python抓取网页并解析
    图解python中赋值、浅拷贝、深拷贝的区别
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2128744.html
Copyright © 2011-2022 走看看