POJ 2074 Line of Sight <几何>

来源:互联网 发布:免费手机库存软件 编辑:程序博客网 时间:2024/05/21 21:38

题目

题目大意:就是求一条线上能够完全看见另一条线的最大连续范围为多大。需要注意的是,障碍线不一定在观光线和房屋线之间,而当障碍线与房屋线或者观光线有重合部分时,也不算遮挡。

分析:求每个障碍线遮挡的范围,最后找到没有遮挡区域的中最长连续区域即可。具体看注释吧。

代码

#include <iostream>#include <cmath>#include <algorithm>#include <iomanip>#include <vector>using namespace std;const double EPS=1e-8;const int MAXN=200;int dblcmp(double x){    return fabs(x)<EPS?0:(x>0?1:-1);}struct Point;typedef Point Vector;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    Vector operator -(Point p){        return Vector(x-p.x,y-p.y);    }    double operator ^(Vector v){ //叉积        return x*v.y-y*v.x;    }};struct Region{ //遮挡区域    double lx,rx;    Region(){}    Region(double _lx,double _rx):lx(_lx),rx(_rx){}};struct Line{    Point p1,p2;    Line(){}    Line(Point _p1,Point _p2):p1(_p1),p2(_p2){}    bool input(){        double x1,x2,y;        cin>>x1>>x2>>y;        if(x1==0&&x2==0&&y==0) return false;        p1=Point(x1,y); p2=Point(x2,y);        return true;    }    double intersectionPointX(Line l){ //定点分比法求交点(x坐标)        double s1=(l.p1-p1)^(p2-p1);        double s2=(l.p2-p1)^(p2-p1);        return (s2*l.p1.x-s1*l.p2.x)/(s2-s1);    }    double length(){        return p2.x-p1.x;    }};Line house,property;vector<Line> obstacles;vector<Region> regions;bool compare(const Region& r1,const Region& r2){    return r1.lx<r2.lx;}void solve(){    int m=obstacles.size();    if(!m){        cout<<fixed<<setprecision(2)<<property.length()<<endl;        return ;    }    regions.clear();    for(int i=0;i<m;++i){ //求每个障碍线的遮挡区域        Point left=obstacles[i].p1;        Point right=obstacles[i].p2;        double x1=property.intersectionPointX(Line(left,house.p2)); //左端点        double x2=property.intersectionPointX(Line(right,house.p1)); //右端点        regions.push_back(Region(max(property.p1.x,x1),min(property.p2.x,x2)));    }    sort(regions.begin(),regions.end(),compare); //排序,方便后面合并相连的遮挡区域    vector<Region> r;    Region region=Region(regions[0].lx,regions[0].rx);    for(int i=1;i<m;++i){ //合并相连的遮挡区域        if(region.rx>regions[i].lx-EPS)            region.rx=max(region.rx,regions[i].rx);        else{            if(region.rx>region.lx) //一开始没有判断这个,wa了好久。。                r.push_back(region);            region=Region(regions[i].lx,regions[i].rx);        }    }    if(region.rx>region.lx)        r.push_back(region);    m=r.size();    double ans=r[0].lx-property.p1.x;    for(int i=0;i<m-1;++i){        ans=max(ans,r[i+1].lx-r[i].rx);    }    ans=max(ans,property.p2.x-r[m-1].rx);    if(ans<EPS) cout<<"No View"<<endl;    else cout<<fixed<<setprecision(2)<<ans<<endl;}int main(){    while(house.input()){        property.input();        int n;        cin>>n;        Line obstacle;        obstacles.clear();        for(int i=0;i<n;++i){            obstacle.input();            if(obstacle.p1.y>house.p1.y-EPS||obstacle.p1.y<property.p1.y+EPS)                continue; //排除不在房屋和观光线之间的            obstacles.push_back(obstacle);        }        solve();    }    return 0;}
原创粉丝点击