这是一道基础几何题,不过久久WA也不知道为什么,参照了http://blog.csdn.net/non_cease/article/details/7773307的不过比较奇怪的不知道为什么非要用C++提交才能过,而G++提交却不能过,题目解法大概如下:
1.房屋的左点与障碍的右点连接成线交于观测线得到一个点a,再用房屋的右点与障碍的左点连接交于观测线得到另一点b,那么两点间的距离就是视线被挡住的部分。
2.求出所有障碍的遮挡部分,然后排序,根据分析然后进行一遍比较就好,不过要注意把观测线的两个端点算上,考虑完全就可以解了,这个题好像没有给出具体数据范围所以还是用动态声请吧,不过真心不知道为什么C++能过G++过不了。
#include<cstdio>
#include<algorithm>
#include<math.h>
using namespace std;
const double eps = 1e-10;
const int maxn=1000;
struct Point {
double x,y;
};
struct Line {
Point a,b;
double left,right;
}house,pro;
int dblcmp(double x){
return x<-eps?-1:x>eps;
}
double getX(Point p1,Point p2, double y){
return (y-p1.y)*(p1.x-p2.x)/(p1.y-p2.y)+p1.x;
}
bool cmp(Line l1,Line l2){
return dblcmp(l1.left-l2.left)<=0;
}
int main(){
double x1,x2,y;
int n;
while(1){
scanf("%lf %lf %lf",&x1,&x2,&y);
if(!dblcmp(x1)&&!dblcmp(x2)&&!dblcmp(y))break;
house.a.x=x1, house.b.x=x2, house.a.y=house.b.y=y;
scanf("%lf %lf %lf",&x1,&x2,&y);
pro.a.x=x1, pro.b.x=x2, pro.a.y=pro.b.y=y;
scanf("%d",&n);
int b_num=0;
Line*ob=new Line[n];//没告诉长度就使用动态声请
for(int i=0;i<n;i++){
scanf("%lf %lf %lf",&x1,&x2,&y);
if(dblcmp(y-house.a.y)>=0||dblcmp(y-pro.a.y)<=0)continue;//不符合的障碍物直接不要算在内,这是个坑
ob[b_num].a.x=x1, ob[b_num].b.x=x2;
ob[b_num].a.y=ob[b_num].b.y=y;
ob[b_num].left=getX(house.b,ob[b_num].a,pro.a.y);
ob[b_num].right=getX(house.a,ob[b_num].b,pro.a.y);
b_num++;
}
sort(ob,ob+b_num,cmp);
double ans=0;
if(dblcmp(ob[0].left-pro.a.x)>0)ans=ob[0].left-pro.a.x;
if(dblcmp(ob[0].right-pro.a.x)<0)ob[0].right=pro.a.x;
int p=0;//表示当前最靠右的点的障碍物下标
double tmp;
for(int i=1; i<b_num; i++){
if(dblcmp(ob[p].right-pro.b.x)>=0)break;//当前最靠右点的下标已经完全挡住了游客
tmp=ob[i].left-ob[p].right;
if(dblcmp(tmp-ans)>0){
i=p;
if(dblcmp(tmp-ans)>0)ans=tmp;
}
else if(dblcmp(ob[i].right-ob[p].right)>0)p=i;
}
tmp=pro.b.x-ob[p].right;
if(dblcmp(tmp-ans)>0)ans=tmp;//处理最右端视线情况
if(dblcmp(ans)>0)printf("%.2lf\n",ans);
else printf("No View\n");
delete [] ob;//释放养成好习惯
}
return 0;
}