zoukankan      html  css  js  c++  java
  • poj2074(求直线的交点)

    题目链接:https://vjudge.net/problem/POJ-2074

    题意:给定L1(Housing Line),L2(properity line),和一些L[i](obstructions line),求L2最长连续区间,使得在该区间能够完整地看见L1(视线不被L[i]遮挡)。

    思路:

      简单几何题。对L[i],计算其遮挡的区间,假设Line( L1.e , L[i].s )和L2交点的横坐标为t1,Line( L1.s , L[i].e )和L2交点的横坐标为t2,那么L[i]遮挡的区间即为[t1,t2],求出所有的遮挡区间后按x坐标排序,遍历一遍求出最长未遮挡区间即可。

    AC code:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    
    const double eps=1e-8;
    const double inf=1e20;
    int sgn(double x){
        if(abs(x)<eps) return 0;
        if(x<0) return -1;
        return 1;
    }
    
    struct Point{
        double x,y;
        Point(){}
        Point(double xx,double yy):x(xx),y(yy){}
        Point operator + (const Point& b)const{
            return Point(x+b.x,y+b.y);
        }
        Point operator - (const Point& b)const{
            return Point(x-b.x,y-b.y);
        }
        double operator * (const Point& b)const{
            return x*b.x+y*b.y;
        }
        double operator ^ (const Point& b)const{
            return x*b.y-b.x*y;
        }
        //绕原点旋转角度b(弧度值),后x、y的变化
        void transXY(double b){
            double tx=x,ty=y;
            x=tx*cos(b)-ty*sin(b);
            y=tx*sin(b)+ty*cos(b);
        }
    };
    
    struct Line{
        Point s,e;
        Line(){}
        Line(Point ss,Point ee){
            s=ss,e=ee;
        }
        //两直线相交求交点
        //第一个值为0表示直线重合,为1表示平行,为2表示相交
        //只有第一个值为2时,交点才有意义
        pair<int,Point> operator &(const Line &b)const{
            Point res = s;
            if(sgn((s-e)^(b.s-b.e)) == 0)
            {
                if(sgn((s-b.e)^(b.s-b.e)) == 0)
                    return make_pair(0,res);//重合
                else return make_pair(1,res);//平行
            }
            double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
            res.x += (e.x-s.x)*t;
            res.y += (e.y-s.y)*t;
            return make_pair(2,res);
        }
    };
    
    double dis(Point a,Point b){
        return sqrt((b-a)*(b-a));
    }
    
    typedef pair<double,double> PDD;
    const int maxn=1005;
    Line L[maxn],L1,L2;
    double x1,x2,y,ans;
    int n,cnt,cnt2;
    PDD pdd[maxn];
    
    bool cmp(PDD p1,PDD p2){
        if(p1.first==p2.first)
            return p1.second<p2.second;
        return p1.first<p2.first;
    }
    
    int main(){
        while(scanf("%lf%lf%lf",&x1,&x2,&y),sgn(x1)||sgn(x2)||sgn(y)){
            L1.s.x=x1,L1.e.x=x2,L1.s.y=L1.e.y=y;
            scanf("%lf%lf%lf",&x1,&x2,&y);
            L2.s.x=x1,L2.e.x=x2,L2.s.y=L2.e.y=y;
            scanf("%d",&n);
            cnt=cnt2=0;
            for(int i=0;i<n;++i){
                scanf("%lf%lf%lf",&x1,&x2,&y);
                if(y>=L1.s.y||y<=L2.s.y) continue;
                L[++cnt].s.x=x1,L[cnt].e.x=x2,L[cnt].s.y=L[cnt].e.y=y;
            }
            for(int i=1;i<=cnt;++i){
                double t1=(L2&(Line(L1.e,L[i].s))).second.x;
                double t2=(L2&(Line(L1.s,L[i].e))).second.x;
                if(t2<L2.s.x||t1>L2.e.x) continue;
                if(t1<L2.s.x) t1=L2.s.x;
                if(t2>L2.e.x) t2=L2.e.x;
                pdd[++cnt2].first=t1,pdd[cnt2].second=t2;
            }
            sort(pdd+1,pdd+cnt2+1,cmp);
            ans=L2.e.x-pdd[cnt2].second;
            double t1=L2.s.x;
            int j=1;
            while(1){
                while(pdd[j].first<t1){
                    t1=max(t1,pdd[j].second);
                    ++j;
                }
                if(j>cnt2) break;
                if(pdd[j].first>=t1){
                    ans=max(ans,pdd[j].first-t1);
                    t1=pdd[j].second;
                    ++j;
                }
                if(j>cnt2) break;
            }
            if(sgn(ans)!=0)
                printf("%.2f
    ",ans);
            else
                printf("No View
    ");
        }
    }
  • 相关阅读:
    数据库设计 一对多 多对多 无限级菜单 设计方法
    线程创建的四种方式
    Linux常用指令---grep(搜索过滤)
    Netty4实战
    linux查找日志技巧
    javascript---关于字符串和数组的方法
    angularJs---route
    JavaScript---详解scroll
    JavaScript--location
    socket中 emit和on的写法
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/11824289.html
Copyright © 2011-2022 走看看