uva221
2016-03-04 20:45
267 查看
Urban Elevations |
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 than101). 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 forthat 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 这题因为数据量不大,所以一开始打算用一个三维数组去慢慢模拟覆盖(不过思路也不是特别清晰),后来看了别人的答案,醍醐灌顶。 思路:检验一座房子的时候,遍历一遍其它的房子,把可以遮挡这座房子的房子抽出来(注意:高度比这座房子矮的,即便有遮挡也不用考虑),然后运用区间覆盖,一个一个遍历,检查这些房子加起来能否挡住这座房子。 代码: #include <cstdio> #include <iostream> #include <algorithm> #include <cstdlib> using namespace std; int n; struct house { int id; double x,y,w,l,h; }all[105],cover[105]; bool cmp(house a,house b) { if(a.x == b.x) return a.y < b.y; return a.x < b.x; } bool judge(int ith) { int cnt = 0; for(int i = 0; i < n; i++) { if(i == ith) continue; if(all[i].y >= all[ith].y) continue; if(all[i].h < all[ith].h) continue; if(all[i].x >= all[ith].x + all[ith].w || all[i].x + all[i].w <= all[ith].x) continue; cover[cnt++] = all[i]; } if(cnt == 0) return true; sort(cover,cover + cnt,cmp); if(cover[0].x > all[ith].x) return true; double tmp = cover[0].x + cover[0].w; for(int i = 1; i < cnt; i++) { if(tmp < cover[i].x) return true; tmp = max(tmp,cover[i].x + cover[i].w); } if(tmp < all[ith].x + all[ith].w) return true; return false; } int main() { int kase = 0; while(cin >> n && n) { for(int i = 0; i < n; i++) { scanf("%lf%lf%lf%lf%lf",&all[i].x,&all[i].y,&all[i].w,&all[i].l ,&all[i].h); all[i].id = i + 1; } sort(all,all + n,cmp); if(kase) cout << endl; printf("For map #%d, the visible buildings are numbered as follows:\n",++kase); cout << all[0].id; for(int i = 1; i < n; i++) { if(judge(i)) cout << " " << all[i].id; } cout << endl; } return 0; }
相关文章推荐
- jQuery新手知识
- jquery中mouseout和mouseleave 事件的区别
- Adaptive Thresholding & Otsu’s Binarization
- OC_Class
- C语言枚举
- 校园网&openwrt记(十一)策略路由实践 游戏端口走校园网关
- poj3469 Dual Core CPU 网络流 sap邻接表模板
- GDKOI2016总结
- 如何把Eclipse工程import Exprot到Android Studio
- saiku源代码安装
- 层次聚类的介绍
- saiku源代码安装
- 联合体以及如何调出内存窗口
- 试一试写博客的感觉
- 动态添加和删除Spinner(ArrayList与Widget的依赖性)
- shell编程(一):简单命令
- C++学习笔记:const_cast类型转化
- 自定义view____通讯录字母特效
- 大规模机器学习 机器学习基础(9)
- 字符数组和字符指针