• 紫书第五章训练 uva 221 Urban Elevations by crq


    An elevation of a collection of buildings is an orthogonal projection of the buildings onto a vertical plane. An external elevation of a city would show the skyline and the faces of the ``visible" buildings of the city as viewed from outside the city from a certain direction. A southern elevation shows no sides; it shows the perfectly rectangular faces of buildings or parts of faces of buildings not obstructed on the south by taller buildings. For this problem, you must write a program that determines which buildings of a city are visible in a southern elevation.
    For simplicity, assume all the buildings for the elevation are perfect rectangular solids, each with two sides that run directly east-west and two running directly north-south. Your program will find the buildings that appear in a southern elevation based on knowing the positions and heights of each city building. That data can be illustrated by a map of the city as in the diagram on the left below. The southern elevation for that city is illustrated in the diagram on the right.

    (The shadow buildings are visible in a southern elevation)


    Input


    Input for your program consists of the numeric description of maps of several cities. The first line of each map contains the number of buildings in the city (a non-negative integer less than 101). Each subsequent line of a map contains data for a single building - 5 real numbers separated by spaces in the following order:

    x-coordinate of the southwest corner

    y-coordinate of the southwest corner

    width of the building (length of the south side)

    depth of the building (length of the west side)

    height of the building

    Each map is oriented on a rectangular coordinate system so that the positive x-axis points east and the positive y-axis points north. Assume that all input for each map corresponds to a legitimate map (the number of buildings is the same as the number of subsequent lines of input for the map; no two buildings in a single map overlap). Input is terminated by the number 0 representing a map with no buildings.


    Output


    Buildings are numbered according to where their data lines appear in the map's input data - building #1 corresponding to the first line of building data, building #2 data to the next line, and building #n to thenth line of building data for that map. (Buildings on subsequent maps also begin their numbering with 1.)
    For each map, output begins with line identifying the map (map #1, map #2, etc.) On the next line the numbers of the visible buildings as they appear in the southern elevation, ordered south-to-north, west-to-east. This means that if building n and building m are visible buildings and if the southwest corner of building nis west of the southwest corner of building m, then number n is printed before number m. If building n and building m have the same x-coordinate for their southwest corners and if building n is south of building m, then the number n is printed before the number m.
    For this program, a building is considered visible whenever the part of its southern face that appears in the elevation has strictly positive area. One blank line must separate output from consecutive input records.


    Sample Input


    14
    160 0 30 60 30
    125 0 32 28 60
    95 0 27 28 40
    70 35 19 55 90
    0 0 60 35 80
    0 40 29 20 60
    35 40 25 45 80
    0 67 25 20 50
    0 92 90 20 80
    95 38 55 12 50
    95 60 60 13 30
    95 80 45 25 50
    165 65 15 15 25
    165 85 10 15 35
    0


    Sample Output


    For map #1, the visible buildings are numbered as follows:
    5 9 4 3 10 2 1 14

    题意分析:给定一系列的房子,问哪些房子没有被其它房子挡住,按照从左到右(x从小到大),从前往后(x相同时y从小到大)顺序输出。首先,将房子按照从左到右,从前往后的顺序排序(即x为第一关键字,y为第二关键字)。这样逐个判断后如果没有被挡住即可以输出。

    在判断某个房子是否被其他房子挡住时,逐个枚举每一个房子,排除掉完全在该房子后面的,左边和右边的,以及比该房子矮的,剩下的才有可能会挡住该房子,将所有可能将其挡住的房子存入数组(这里用vector存储),根据从左到右,从前往后排序后,逐个判断该房子能否从某个房子的左边露出,如果左边全部无法露出,则最后需要判断能否从右边露出。

    AC源码:

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 struct Build
     7 {
     8     int x, y;
     9     int w, d, h;
    10     int id;
    11 };
    12 
    13 vector<Build> vec1, vec2;
    14 bool cmp(const Build& a, const Build& b)
    15 {
    16     if (a.x != b.x)
    17         return a.x < b.x;
    18     return a.y < b.y;
    19 }
    20 
    21 bool judge(int k)//判断有没有挡住k的 
    22 {
    23     vec2.clear();
    24     for (int i = 0; i < vec1.size(); i++)
    25     {
    26         if (i == k)//自己
    27             continue;
    28         if(vec1[i].y>=vec1[k].y)//在k后面的 
    29             continue;
    30         if(vec1[i].x>=vec1[k].x+vec1[k].w)//完全在k的右边 
    31             continue;
    32         if(vec1[i].x+vec1[i].w<=vec1[k].x)//完全在k的左边 
    33             continue;
    34         if(vec1[i].h<vec1[k].h)//比k矮 
    35             continue;
    36         vec2.push_back(vec1[i]);//挡住,记录 
    37     }
    38     if (vec2.size() == 0)
    39         return true;//挡不住 
    40     int t = vec1[k].x;
    41     sort(vec2.begin(), vec2.end(), cmp);
    42     for (int i = 0; i < vec2.size(); i++)
    43     {
    44         if (t < vec2[i].x)//找到有一部分是否左边露出 
    45             return true;
    46         t = max(t, vec2[i].x + vec2[i].w);
    47     }
    48     return t < vec1[k].x + vec1[k].w;//右边露出 
    49 }
    50 
    51 int main ()
    52 {
    53     int cas = 0, n;
    54     while (scanf("%d", &n), n)
    55     {
    56         vec1.clear();
    57         if (cas)
    58             printf("
    ");
    59         cas++; 
    60         for (int i = 0; i < n; i++)
    61         {
    62             Build b;
    63             cin>>b.x>>b.y>>b.w>>b.d>>b.h;
    64             b.id = i+1;
    65             vec1.push_back(b);
    66         }
    67         cout<<"For map #"<<cas<<", the visible buildings are numbered as follows:"<<endl;
    68         sort(vec1.begin(), vec1.end(), cmp);
    69         int flag = 0;
    70         for (int i = 0; i < vec1.size(); i++)
    71         {
    72             if (judge(i))
    73             {
    74                 if (flag++)
    75                     cout<<" ";
    76                 cout<<vec1[i].id;
    77             }
    78         }
    79         cout<<endl;
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    python中类(class)和实例(instance)
    python面向对象
    python中初始化实例属性
    python之使用__future__(解决版本不同,不兼容问题)
    python中动态导入模块
    python之导入模块
    python中偏函数
    python中完善decorator
    python中编写带参数decorator
    python中编写无参数decorator
  • 原文地址:https://www.cnblogs.com/tzcacm/p/6846324.html
Copyright © 2020-2023  润新知