poj 2074 Line of Sight

有一个trick就是如果house和 property line之间没有障碍物直接输出property line的长度即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
struct P
{
    double x,y;
    P (){}
    P (double x,double y):x(x),y(y){
    }
    P operator -(P p){
        return P(x-p.x,y-p.y);
    }
    P operator +(P p){
        return P(x+p.x,y+p.y);
    }
    P operator *(double d){
        return P(x*d,y*d);
    }
    double det(P p){
        return (x*p.y)-(y*p.x);
    }
};
struct Line
{
    P a,b;
};
Line H,p;
Line qs[100000],jiaodian[100000],jiaodian1[100000];
bool judge(P a,P b,P c,P d)
{
    if((c-a).det(b-a)*(d-a).det(b-a)<=0)
    return 1;
    return 0;
}
P in(P a,P b,P c,P d)
{
    return c+(d-c)*((b-a).det(a-c) / (b-a).det(d-c));
}
double dis(P a,P b)
{
    double c=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    return sqrt(c);
}
bool cmp(Line a,Line b)
{
    if(a.a.x!=b.a.x)
    return a.a.x<b.a.x;
    return a.b.x<b.b.x;
}
bool cmp1(Line a,Line b)
{
	return a.b.x<b.b.x;
}
int main()
{
    double x1,x2,y1;
    while(~scanf("%lf%lf%lf",&x1,&x2,&y1))
    {
		int i;
        if(x1==0 && x2==0 && y1==0)
        break;
        H.a.x=x1;H.a.y=y1;
        H.b.x=x2;H.b.y=y1;
        scanf("%lf%lf%lf",&p.a.x,&p.b.x,&p.a.y);
        p.b.y=p.a.y;
        int k,l=0,l1=0,l2=0;
        scanf("%d",&k);
        while(k--)
        {
            scanf("%lf%lf%lf",&x1,&x2,&y1);
				if(x1>p.b.x || x2<p.a.x)
				continue;
            if(y1>min(H.a.y,p.a.y) && y1<max(H.a.y,p.a.y))
            {
                qs[l].a.x=x1;
                qs[l].b.x=x2;
                qs[l].a.y=qs[l].b.y=y1;
                l++;
            }
        }
		if(l==0)
		{
			printf("%.2lf\n",p.b.x-p.a.x);
			continue;
		}
        for( i=0;i<l;i++)
        {
			P lf,rg;
			lf=in(H.b,qs[i].a,p.a,p.b);
			rg=in(H.a,qs[i].b,p.a,p.b);
            if(judge(H.b,qs[i].a,p.a,p.b))
            jiaodian[l1].a=in(H.b,qs[i].a,p.a,p.b);
            else
            {jiaodian[l1].a.x=p.a.x;jiaodian[l1].a.y=p.a.y;}

            if(judge(H.a,qs[i].b,p.a,p.b))
            jiaodian[l1].b=in(H.a,qs[i].b,p.a,p.b);
            else
            {jiaodian[l1].b.x=p.b.x;jiaodian[l1].b.y=p.b.y;}
            l1++;
			if(lf.x>p.b.x || rg.x<p.a.x)
				l1--;
		//	printf("%lf %lf\n",jiaodian[l1-1].a.x,jiaodian[l1-1].b.x);
        }
		for(i=0;i<l1;i++)
		{
			int fg=1;
			for(int j=0;j<l1;j++)
			{
				if(i==j)
					continue;
				if(jiaodian[i].a.x>=jiaodian[j].a.x && jiaodian[i].b.x<=jiaodian[j].b.x)
					fg=0;
			}
			if(fg)
				jiaodian1[l2++]=jiaodian[i];
		}
        sort(jiaodian1,jiaodian1+l2,cmp);
        double ans=dis(p.a,jiaodian1[0].a);
        for( i=0;i<l2-1;i++)
        {
            int fg=1;
            Line hehe;
            hehe.a.x=0x7ffffff;
		//	printf("%lf %lf\n",jiaodian1[i].a.x,jiaodian1[i].b.x);
            for(int j=i+1;j<l2;j++)
            {
                if(jiaodian1[j].a.x<=jiaodian1[i].b.x)
                fg=0;
                else
                {
                    if(jiaodian1[j].a.x<hehe.a.x)
                        hehe=jiaodian1[j];
                }
            }
            if(fg)
            {
                double ans1=dis(jiaodian1[i].b,hehe.a);
                if(ans1>ans)
                ans=ans1;
            }
        }
		sort(jiaodian1,jiaodian1+l2,cmp1);
        double llll=dis(jiaodian1[l2-1].b,p.b);
        if(llll>ans)
        ans=llll;
        if(ans!=0)
        printf("%.2lf\n",ans);
        else
        printf("No View\n");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值