poj 2074 Line of Sight

//主要思想,遍历每一个障碍,求出它在property line上挡住的范围cover[i],然后线性扫描这些cover,找出最大值。

//此代码一开始g++交不过,c++才能过,后来才知道G++标准的浮点型输出用%f 而不是%lf。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace
std;
const
double EP=1e-8;
struct
Point{double x, y;}p;
struct
Line{double a, b, c;}pl;
struct
Segline{Point s, e;}sg,cover[1002],house,pline;
Line makeline(Point p1, Point p2){
    Line t1;
    int
sign=1;
    t1.a=p2.y-p1.y;
    if
(t1.a<0){
        t1.a*=-1;
        sign=-1;
    }

    t1.b=sign*(p1.x-p2.x);
    t1.c=sign*(p1.y*p2.x-p1.x*p2.y);
    return
t1;
}

void
lineintersect(Line l1, Line l2, Point &p){
    double
t1=l1.a*l2.b-l2.a*l1.b;
    p.x=(l2.c*l1.b-l1.c*l2.b)/t1;
    p.y=(l2.a*l1.c-l1.a*l2.c)/t1;
}

bool
cmp(Segline s1, Segline s2){
    if
(s2.s.x-s1.s.x>-EP)
    return
true;
    return
false;
}

int
main(){
    //freopen("1.txt", "r", stdin);
    int i, n, sum;
    double
len, covery;
    while
(scanf("%lf %lf %lf",&house.s.x, &house.e.x, &house.s.y)!=EOF){
        if
(!house.s.x&&!house.e.x&&!house.s.y)
        break
;
        house.e.y=house.s.y;sum=0;
        scanf("%lf %lf %lf %d",&pline.s.x, &pline.e.x, &pline.s.y, &n);
        pline.e.y=pline.s.y;
        pl=makeline(pline.s,pline.e);
        for
(i=0; i<n; i++){
            scanf("%lf %lf %lf", &sg.s.x, &sg.e.x, &sg.s.y);
            sg.e.y=sg.s.y;
            if
(sg.s.y-house.s.y>-EP||pline.s.y-sg.s.y>-EP)
                continue
;
            Line l;
            l=makeline(house.e,sg.s);
            lineintersect(l, pl, p);
            if
(p.x>pline.e.x)
                continue
;
            cover[sum].s=p;
            l=makeline(house.s,sg.e);
            lineintersect(l, pl, p);
            if
(p.x<pline.s.x)
                continue
;
            cover[sum].e=p;
            sum++;
        }

        if
(sum==0){
            printf("%.2lf/n",pline.e.x-pline.s.x);
            continue
;
        }

        sort(cover,cover+sum,cmp);
        if
(cover[0].s.x-pline.s.x<EP)
        len=0;
        else
len=cover[0].s.x-pline.s.x;
        covery=cover[0].e.x;
        for
(i=1; i<sum; i++){
            if
(cover[i].s.x-covery>len)
            len=cover[i].s.x-covery;
            if
(cover[i].e.x>covery)
                covery=cover[i].e.x;
        }

        if
(pline.e.x-covery>len)
            len=pline.e.x-covery;
        if
(len<EP)
        printf("No View/n");
        else
printf("%.2f/n", len);
    }

    return
0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值