POJ 2074 Line of Sight

来源:互联网 发布:土木工程网络教育本科 编辑:程序博客网 时间:2024/05/17 01:10

思路很清晰。


首先排除掉不在house和pro之间的障碍物

然后对每个障碍物,将站在直线上不能看到整个house的区间求出来。

最后对这些区间,扫一遍,贪心求一下即可

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <cstdlib>#include <cmath>#include <map>#include <sstream>#include <queue>#include <vector>#define MAXN 100005#define MAXM 211111#define eps 1e-8#define INF 50000001using namespace std;inline int dblcmp(double d){    if(fabs(d) < eps) return 0;    return d > eps ? 1 : -1;}struct point{    double x, y;    point(){}    point(double _x, double _y): x(_x), y(_y) {}    void input()    {        scanf("%lf%lf", &x, &y);    }    bool operator ==(point a)const    {        return dblcmp(a.x - x) == 0 && dblcmp(a.y - y) == 0;    }    point sub(point p)    {        return point(x - p.x, y - p.y);    }    double dot(point p)    {        return x * p.x + y * p.y;    }    double det(point p)    {        return x * p.y - y * p.x;    }    double distance(point p)    {        return hypot(x - p.x, y - p.y);    }}p[5555];struct line{    point a, b;    line(){}    line(point _a, point _b){ a = _a; b = _b;}    void input()    {        a.input();        b.input();    }    point crosspoint(line v)    {        double a1 = v.b.sub(v.a).det(a.sub(v.a));        double a2 = v.b.sub(v.a).det(b.sub(v.a));        return point((a.x * a2 - b.x * a1) / (a2 - a1), (a.y * a2 - b.y * a1) / (a2 - a1));    }}house, pro;bool cmp(point a, point b){    int k = dblcmp(a.x - b.x);    if(k < 0) return 1;    else if(k > 0) return 0;    else return dblcmp(a.y - b.y) < 0;}int main(){    double xa, ya, xb;    int m;    while(scanf("%lf%lf%lf", &xa, &xb, &ya) != EOF)    {        if(dblcmp(xa) == 0 && dblcmp(xb) == 0 && dblcmp(ya) == 0) break;        house = line(point(xa, ya), point(xb, ya));        scanf("%lf%lf%lf", &xa, &xb, &ya);        pro = line(point(xa, ya), point(xb, ya));        scanf("%d", &m);        int cnt = 0;        for(int i = 0; i < m; i++)        {            scanf("%lf%lf%lf", &xa, &xb, &ya);            if(dblcmp(ya - house.a.y) >= 0 || dblcmp(ya - pro.a.y) <= 0) continue;            line tmp = line(point(xa, ya), house.b);            point p1 = tmp.crosspoint(pro);            tmp = line(point(xb, ya), house.a);            point p2 = tmp.crosspoint(pro);            if(dblcmp(p1.x - pro.b.x) > 0 || dblcmp(p2.x - pro.a.x) < 0) continue;            p[cnt].x = max(pro.a.x, p1.x);            p[cnt++].y = min(pro.b.x, p2.x);        }        double ans = 0;        if(cnt)        {            sort(p, p + cnt, cmp);            double lst = pro.a.x;            for(int i = 0; i < cnt; i++)            {                if(dblcmp(p[i].x - lst) > 0) ans = max(ans, p[i].x - lst), lst = p[i].y;                else if(dblcmp(p[i].y - lst) > 0) lst = p[i].y;            }            if(dblcmp(lst - pro.b.x) < 0) ans = max(ans, pro.b.x - lst);        }        else ans = pro.b.x - pro.a.x;        if(dblcmp(ans) == 0) printf("No View\n");        else printf("%.2f\n", ans);    }    return 0;}