Line of Sight
Time Limit: 1000MS |
|
Memory Limit: 30000K |
Total Submissions: 1406 |
|
Accepted: 423 |
Description
An architect is very proud of his new home and wants to be sure it can be seen by people passing by his property line along the street. The property contains various trees, shrubs, hedges, and other obstructions that may block the view. For the purpose of this problem, model the house, property line, and obstructions as straight lines parallel to the x axis:
To satisfy the architect's need to know how visible the house is, you must write a program that accepts as input the locations of the house, property line, and surrounding obstructions and calculates the longest continuous portion of the property line from which the entire house can be seen, with no part blocked by any obstruction.
Input
Because each object is a line, it is represented in the input file with a left and right x coordinate followed by a single y coordinate:
< x1 > < x2 > < y >
Where x1, x2, and y are non-negative real numbers. x1 < x2
An input file can describe the architecture and landscape of multiple houses. For each house, the first line will have the coordinates of the house. The second line will contain the coordinates of the property line. The third line will have a single integer that represents the number of obstructions, and the following lines will have the coordinates of the obstructions, one per line.
Following the final house, a line "0 0 0" will end the file.
For each house, the house will be above the property line (house y > property line y). No obstruction will overlap with the house or property line, e.g. if obstacle y = house y, you are guaranteed the entire range obstacle[x1, x2] does not intersect with house[x1, x2].
Output
For each house, your program should print a line containing the length of the longest continuous segment of the property line from which the entire house can be to a precision of 2 decimal places. If there is no section of the property line where the entire house can be seen, print "No View".
Sample Input
2 6 6
0 15 0
3
1 2 1
3 4 1
12 13 1
1 5 5
0 10 0
1
0 15 1
0 0 0
Sample Output
8.80
No View
Source
Mid-Atlantic 2004
/* 每次读到障碍物需要计算当前障碍物产生的不能完全看到房子的区域,并将其存储起来, 然后对所有不可见区域按照左端的坐标值进行排序,最后线性扫描排序后的不可见区域 统计这些区域没有覆盖的最大可见区域,需要注意的地方有: (1)障碍物可能和房子平行甚至在房子上方 (2)障碍物可能在地平线上甚至在地平线以下 (3)别忘了统计最有一个端点的lastX离障碍物最右侧的距离 */ #include <iostream> #include <algorithm> #include <cmath> #define MAX_N 1000 #define EPS 1E-8 #define minv(a, b) ((a) <= (b) ? (a) : (b)) #define maxv(a, b) ((a) >= (b) ? (a) : (b)) using namespace std; double hx1, hx2, hy; double lx1, lx2, ly; struct ob { double x1, x2; }obs[MAX_N]; int on; bool compare(const ob &o1, const ob &o2) { return (fabs(o1.x1 - o2.x1) < EPS) ? o1.x2 + EPS < o2.x2 : o1.x1 + EPS < o2.x1; } double getPos(double ox, double oy, double hx, double hy) { if(ox == hx) return ox; return ox + (ly - oy) / ((oy - hy) / (ox - hx)); } int main() { int tempon, i; while(scanf("%lf%lf%lf", &hx1, &hx2, &hy) && !((hx1 + hx2 + hy) < EPS)) { double ox1, ox2, oy; on = 0; scanf("%lf%lf%lf", &lx1, &lx2, &ly); scanf("%d", &tempon); for(i = 0; i < tempon; i++) { scanf("%lf%lf%lf", &ox1, &ox2, &oy); if(oy + EPS < ly || fabs(oy - ly) < EPS || oy >= hy + EPS || fabs(oy - hy) < EPS) continue; double tempx1 = getPos(ox1, oy, hx2, hy); double tempx2 = getPos(ox2, oy, hx1, hy); if(tempx1 > lx2 + EPS || tempx2 + EPS < lx1) continue; obs[on].x1 = maxv(tempx1, lx1); obs[on++].x2 = minv(tempx2, lx2); } double maxLen = 0; if(on != 0) { sort(obs, obs + on, compare); double lastX = lx1; for(i = 0; i < on; i++) { if(obs[i].x1 > lastX + EPS) { maxLen = maxv(maxLen, obs[i].x1 - lastX); lastX = obs[i].x2; } else if(obs[i].x2 > lastX + EPS) lastX = obs[i].x2; } //一开始忘记这个了无限WA if(lastX + EPS < lx2) maxLen = maxv(maxLen, lx2 - lastX); } else maxLen = lx2 - lx1; if(fabs(maxLen) < EPS) printf("No View/n"); else printf("%.2lf/n", maxLen); } return 0; }