[poj] 2074 Line of Sight || 直线相交求交点

原题

给出一个房子(线段)的端点坐标,和一条路的两端坐标,给出一些障碍物(线段)的两端坐标。问在路上能看到完整房子的最大连续长度是多长。


将障碍物按左端点坐标排序,然后用房子的右端与障碍物的左端连线,房子的左端和前一障碍物的右端比较,得出在道路上的能看到的长度取Max即可

#include<cstdio>
#include<algorithm>
using namespace std;
double a,b,c,l,lmx,ans;
int n,pos;
struct point
{
    double x,y;
    bool operator < (const point &b) const
	{
	    if (x==b.x) return y<b.y;
	    return x<b.x;
	}
    bool operator == (const point &b) const
	{
	    return x==b.x && y==b.y;
	}
}p1,p2,p3,p4;
struct hhh
{
    point left,right;
    void init(double a,double b,double c)
	{
	    left.x=a;
	    right.x=b;
	    left.y=right.y=c;
	}
    bool operator < (const hhh &b) const
	{
	    if (left==b.left) return right<b.right;
	    return left<b.left;
	}
}house,surplus[110],line;

double max(double x,double y) { return x>y?x:y; }
double min(double x,double y) { return x<y?x:y; }

double find(point a,point b,point c,point d)
{
    double tmp=((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));
    return  (b.x-a.x)*tmp+a.x;
}

int main()
{
    while (~scanf("%lf%lf%lf",&a,&b,&c))
    {
	if (a==0 && b==0 && c==0) break;
	house.init(a,b,c);
	scanf("%lf%lf%lf",&a,&b,&c);
	line.init(a,b,c);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
	    scanf("%lf%lf%lf",&a,&b,&c);
	    surplus[i].init(a,b,c);
	}
	sort(surplus+1,surplus+n+1);
	lmx=ans=-1;
	p3=line.left;
	p4=line.right;
	for (int i=1;i<=n+1;i++)
	{
	    double l,r;
	    if (surplus[i].left.y>=house.left.y) continue;
	    if (i==1) l=line.left.x;
	    else
	    {
		p1=house.left;
		p2=surplus[i-1].right;
		l=find(p1,p2,p3,p4);
	    }
	    if (i==n+1) r=line.right.x;
	    else
	    {
		p1=house.right;
		p2=surplus[i].left;
		r=find(p1,p2,p3,p4);
	    }
	    l=max(l,line.left.x);
	    r=min(r,line.right.x);
	    l=max(l,lmx);
	    lmx=max(lmx,l);
	    ans=max(ans,r-l);
	}
	if (ans<=0) printf("No View\n");
	else printf("%.2f\n",ans);
    }
    return 0;
}
posted @ 2018-01-01 19:07  Mrha  阅读(142)  评论(0编辑  收藏  举报