原题传送门:http://poj.org/problem?id=2074
博主的中文题面(坑爹POJ):
https://www.luogu.org/problemnew/show/T22869
Line of Sight
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
题目大意
在二维平面中有多条平行与x轴的线段,求其中某一条线段(路)上能完整看到另一条线段(房子)的最长连续线段的长度。
题解
我们可以先求出所有盲区,按左端点从小到大排序,最后从左到右扫描一波,不断更新最大非盲区的值并合并盲区。
关于盲区的求解,只需要将房子的左右端点分别与障碍物右左端点连接(注意顺序),做出直线求解其与路的交点就行了。
坑
障碍物不一定在房子和道路中间,需要特判甩到一个很远的地方。障碍物不会和房子重合,但是可能共线,需要特判。
另外,博主的代码C++ AC,G++ WA,不知道为什么(黑人问号)。
代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define db double
using namespace std;
const db eps=1e-8;
const int inf=-1e9;
struct pt{db x,y;};
int sig(db a){return (a>eps)-(a<-eps);}
db inter(db a1,db a2,db b1,db b2,db c1,db c2,db d1,db d2)
{
if(!sig(a1-b1)) return a1;
db k=(b2-a2)/(b1-a1);
return (a2-c2-k*a1)/(-k);
}
struct sd{
db le,ri;
bool operator < (const sd &a) const
{
return le<a.le;
}
};
sd bli[110];
pt hle,hri;
db lmax,rmax,low;
int m;
db hh(db a)
{
if(a<lmax) return lmax;
return a<rmax?a:rmax;
}
void work(db a,db b,db c,int p)
{
if(sig(hle.y-c)<=0||sig(c-low)<0) a=b=c=-inf;
bli[p].le=hh(inter(a,c,hri.x,hri.y,lmax,low,rmax,low));
bli[p].ri=hh(inter(b,c,hle.x,hle.y,lmax,low,rmax,low));
}
void in()
{
if(!hle.x&&!hri.x&&!hle.y) exit(0);
scanf("%lf%lf%lf%d",&lmax,&rmax,&low,&m);
hri.y=hle.y;
db a,b,c;
for(int i=1;i<=m;++i)
scanf("%lf%lf%lf",&a,&b,&c),work(a,b,c,i);
}
void ac()
{
// printf("---------\n");
// for(int i=1;i<=m;++i)
// printf("%.2lf %.2lf\n",bli[i].le,bli[i].ri);
// printf("---------\n");
sort(bli+1,bli+1+m);
bli[0].le=bli[0].ri=lmax;
bli[m+1].le=bli[m+1].ri=rmax;
m+=1;
db ans=-1.0,p2=bli[0].ri;
for(int i=1;i<=m;++i)
{
if(bli[i].le>p2) ans=max(ans,bli[i].le-p2);
p2=max(p2,bli[i].ri);
}
if(sig(ans)>0) printf("%.2lf\n",ans);
else printf("No View\n");
memset(bli,0,sizeof(bli));
}
int main()
{
// freopen("data.out","w",stdout);
while(scanf("%lf%lf%lf",&hle.x,&hri.x,&hle.y)==3)
{
in();ac();
}
return 0;
}