解题报告 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 的某道题(跌落的世界、立体图。。。神马的)的影响,本人一看到图形题就发虚,其实图形题不一定有多难。

posted @ 2011-08-05 16:07  木小漾  阅读(376)  评论(0编辑  收藏  举报