题目链接:http://poj.org/problem?id=2074
————————————————————————————
题目大意: 求property line上能看到房子全貌的最长段
————————————————————————————
题目思路: 先求出来每条障碍物线遮挡property line的线段,对线段的左端点进行排序。
从最左一条开始扫描,考察他前面的所有线段中,右端点最远的一条线段和本线段之间的关系,进行分类讨论
————————————————————————————
题目细节:
1、障碍线可能在house的上面或者与house平行,或者有可能在property的下面或与其平行。
2、在第一条线段左端点的左边和最右的右端点的右边 可能需要计算
3、这题需要用double才能过,且选用c++过不了,需要选g++(木有搞清楚为毛)
————————————————————————————
这题改了好几遍,代码的逻辑不清楚了,凑和着看吧。。
源代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
typedef double T;
struct Pt
{
T x;
T y;
T len;
Pt(){}
Pt(T px,T py)
{
x = px;
y = py;
}
Pt &operator +(const Pt &p) const
{
Pt c;
c.x = x + p.x;
c.y = y + p.y;
return c;
}
Pt &operator -(const Pt &p) const
{
Pt c;
c.x = x - p.x;
c.y = y - p.y;
return c;
}
};
struct Line
{
Pt a;
Pt b;
int cont;
Line(){}
Line (Pt p1,Pt p2)
{
a = p1;
b = p2;
}
};
Line line[10000],house,road,cur;
bool cmp(Line l1,Line l2)
{
return l1.a.x < l2.a.x;
}
Pt seg(Pt a,Pt b)
{
T x = 0;
x = a.x + (b.x - a.x)*(road.a.y - a.y)/(b.y - a.y);
return Pt(x,road.a.y);
}
double max(double a,double b)
{
if(a>b) return a;
else return b;
}
int main()
{
int i = 0,n = 0,j = 0;
T x1,x2,y;
T ans = 0;
T temp = 0;
int flag = 0;
scanf("%lf%lf%lf",&x1,&x2,&y);
while(x1||x2||y)
{
house = Line(Pt(x1,y),Pt(x2,y));
scanf("%lf%lf%lf",&x1,&x2,&y);
road = Line(Pt(x1,y),Pt(x2,y));
if(house.a.y == road.a.y)
{
printf("No View\n");
continue;
}
scanf("%d",&n);
for(i = 0;i<n;i++)
{
scanf("%lf%lf%lf",&x1,&x2,&y);
if(y>=house.a.y || y<=road.a.y)
{
n--;
i--;
continue;
}
cur = Line(Pt(x1,y),Pt(x2,y));
line[i] = Line(seg(house.b,cur.a),seg(house.a,cur.b));
}
sort(line,line+n,cmp);
ans = 0;
if(line[0].a.x>road.a.x && n>0)
ans = line[0].a.x - road.a.x;
for(i = 1;i<n;i++)
{
if(line[i].a.x<=road.a.x) continue;
temp = road.a.x;
for(j = 0;j<i;j++)
{
if(line[j].b.x > temp) temp = line[j].b.x;
}
if(temp>line[i].a.x) continue;
else
{
if(temp>road.b.x) break;
else if(line[i].a.x>road.b.x)
{
ans = max(road.b.x - line[i-1].a.x,ans);
break;
}
else ans = max(line[i].a.x-temp,ans);
}
}
if(n == 1)
{
double a = 0,b = 0;
double c = road.b.x - road.a.x;
if(line[0].a.x>road.a.x) a = line[0].a.x - road.a.x;
if(line[0].b.x<road.b.x) b = road.b.x - line[0].b.x;
if(a>c) a = c;
if(b>c) b = c;
ans = max(a,b);
}
else
{
flag = 0;
for(i = 0;i<n;i++)
{
if(line[i].b.x>=road.b.x)
{
flag = 1;
break;
}
}
if(!flag) ans = max(road.b.x - line[n-1].b.x,ans);
}
if(ans == 0.0)
printf("No View\n");
else
printf("%.2f\n",ans);
scanf("%lf%lf%lf",&x1,&x2,&y);
}
return 0;
}