• 【题解】Railway [Uva10263]


    【题解】Railway [Uva10263]

    传送门:( ext{Railway [Uva10263]})

    【题目描述】

    给出点 (M) 以及一个由 (n) 条线段依次相连的类曲形图(由 (n+1) 个点构成),求该“曲形”图中距离点 (M) 最近的点 (P) 的坐标((P) 可以在任意一条线段上)。

    【输入】

    输入多组数据,读至 (EOF) 结束。

    每组数据第一、二行为点 (M) 的坐标,接下来一个整数 (n) 以及 (2(n+1)) 行表示 (n+1) 的点的坐标。

    【输出】

    对于每组数据,输出两行分别表示点 (P) 的横、纵坐标。

    【样例】

    样例输入:
    6
    -3
    3
    0
    1
    5
    5
    9
    -5
    15
    3
    0
    0
    1
    1
    0
    2
    0
    样例输出:
    7.8966
    -2.2414
    1.0000
    0.0000
    

    【分析】

    【计算几何全家桶】

    计算几何基础题。

    在输入时记录上一个点的坐标,分别求点 (M)(n) 条线段的最短距离即可。

    ((1).) 求点 (P) 到线段 (AB) 最短距离:

    先判断垂足 (F) 的位置,如果在 (AB) 的延长线上,则最短距离为 (PB),如果在 (BA) 的延长线上,则最短距离为 (PA),否则为 (PF)

    ((2).) 求点 (P) 到线段 (AB) 的垂足 (F)

    分别计算 (AP,BP)(AB,BA) 上的投影并作比,得到 (AF)(AB) 的比,而 (AB) 已知,则可得点 (AF),最后再算出 (F)

    【Code】

    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #define LD double
    #define LL long long
    #define Vector Point
    #define Re register int
    using namespace std;
    const int N=1e5+3;
    const LD eps=1e-8;
    int n;
    inline int dcmp(LD a){return a<-eps?-1:(a>eps?1:0);}
    inline LD Abs(LD a){return a*dcmp(a);}
    struct Point{
        LD x,y;Point(LD X=0,LD Y=0){x=X,y=Y;}
        inline void in(){scanf("%lf%lf",&x,&y);}
    }M,P1,P2;
    inline LD Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}
    inline LD Cro(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
    inline LD Len(Vector a){return sqrt(Dot(a,a));}
    inline LD Angle(Vector a,Vector b){return acos(Dot(a,b)/Len(a)/Len(b));}
    inline Point operator+(Point a,Vector b){return Point(a.x+b.x,a.y+b.y);}
    inline Vector operator-(Point a,Point b){return Vector(a.x-b.x,a.y-b.y);}
    inline Vector operator*(Vector a,LD x){return Vector(a.x*x,a.y*x);}
    inline bool operator==(Point a,Point b){return !dcmp(a.x-b.x)&&!dcmp(a.y-b.y);}
    struct ANS{Point a;LD dis;ANS(Point A,LD D=0){a=A,dis=D;}};
    inline Point FootPoint(Point p,Point a,Point b){//点P到直线AB的垂足
        Vector x=p-a,y=p-b,z=b-a;
        LD len1=Dot(x,z)/Len(z),len2=-1.0*Dot(y,z)/Len(z);//分别计算AP,BP在AB,BA上的投影
        return a+z*(len1/(len1+len2));//点A加上向量AF
    }
    inline Point dis_PL(Point p,Point a,Point b){//点P到线段AB距离
        if(a==b)return a;//AB重合
        Vector x=p-a,y=p-b,z=b-a;
        if(dcmp(Dot(x,z))<0)return a;//P距离A更近
        if(dcmp(Dot(y,z))>0)return b;//P距离B更近
        return FootPoint(p,a,b);//返回垂足
    }
    int main(){
    //  freopen("123.txt","r",stdin);
        while(~scanf("%lf%lf",&M.x,&M.y)){
            scanf("%d",&n),P1.in();
            Point ans=P1;
            while(n--){
                P2.in();Point tmp=dis_PL(M,P1,P2);
                if(dcmp(Len(M-tmp)-Len(M-ans))<0)ans=tmp;
                P1=P2;
            }
            printf("%.4lf
    %.4lf
    ",ans.x,ans.y);
        }
    }
    
  • 相关阅读:
    MongoDB查询
    MongoDB增删改查
    redis复制
    HTTP请求方法与状态码
    Solr工作原理
    idea多行同一列同时编辑;多光标处同时编辑方法
    SVN merge 三种方式
    vue中msgbox的使用;如何在msgbox中新增一个输入框组件传值给后台
    切换或重新输入svn用户名密码或通过tortoisesvn查看svn密码
    MyBatis中#{}和${}的区别
  • 原文地址:https://www.cnblogs.com/Xing-Ling/p/12102783.html
Copyright © 2020-2023  润新知