• uva 11796 Dog Distance


    题意:给定两条狗的行走路线,一直两条狗同时出发同时到达,问路途中的最远和最近距离。

    思路:先简化版本,如果甲乙都仅沿着两条线段向前跑,那么他们之间的最短和最长距离怎么算? 假设甲的速度向量为v1(速度向量指甲单位时间所走的位移向量),乙的速度向量为v2. 因为运动是相对的,可以把甲看成是静止的,乙运动,因此问题转化成求最小的点到线段的最小或最大距离。(可以把甲看成是静止不动的,而让乙一个人以v2-v1的速度向量去运动)

    画图证明一下:乙一个人以v2-v1的速度运动时,包含的距离组成的集合一定包含了甲乙同时运动时的距离集。

    那么,我们对于每段分析,看谁先到达该线段的终点,则该段可以用上面的方法求。

    把a看成不动的,则有b运动到了cb+vb-va(其中va,vb分别为a和b的位移向量,ca,cb分别为a和b初始位置)

    那么就转换为sa到线段cb+vb-va的距离。(最小距离为点到直线,而最大距离一定在线段两边)

    解完之后,还要更新甲乙的位置,如果正好到达下一个拐点,还要更新Sa和Sb。

    复杂度(A+B)

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<iostream>
      6 #include<memory.h>
      7 #include<cstdlib>
      8 #include<vector>
      9 #define clc(a,b) memset(a,b,sizeof(a))
     10 #define LL long long int
     11 using namespace std;
     12 const int inf=0x3f3f3f3f;
     13 const double eps = 1e-10;
     14 const int N = 300 + 5;
     15 const double pi= acos(-1.0);
     16 
     17 struct Point
     18 {
     19     double x,y;
     20     Point(double x=0,double y=0):x(x),y(y) {}
     21 };
     22 
     23 typedef Point Vector;
     24 
     25 Vector operator +(Vector A,Vector B)   //向量+向量=向量,向量+点=点
     26 {
     27     return Vector(A.x+B.x,A.y+B.y);
     28 }
     29 
     30 Vector operator -(Point A,Point B)   //点-点=向量
     31 {
     32     return Vector(A.x-B.x,A.y-B.y);
     33 }
     34 
     35 Vector operator *(Vector A,double p)   //向量*数=向量
     36 {
     37     return Vector(A.x*p,A.y*p);
     38 }
     39 
     40 Vector operator /(Vector A,double p)   //向量/数=向量
     41 {
     42     return Vector(A.x/p,A.y/p);
     43 }
     44 
     45 bool operator <(const Point &a,const Point &b)
     46 {
     47     return a.x<b.x||(a.x==b.x&&a.y<b.y);
     48 }
     49 
     50 int dcmp(double x)
     51 {
     52     if(fabs(x)<eps) return 0;
     53     else
     54         return x<0?-1:1;
     55 }
     56 
     57 bool operator ==(const Point &a,const Point &b)
     58 {
     59     return  dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
     60 }
     61 
     62 double Dot(Vector A,Vector B)   //求点积
     63 {
     64     return A.x*B.x+A.y*B.y;
     65 }
     66 
     67 double Length(Vector A)   //利用点积求向量长度
     68 {
     69     return sqrt(Dot(A,A));
     70 }
     71 
     72 double Angle(Vector A,Vector B)   //利用点积求夹角
     73 {
     74     return acos(Dot(A,B)/Length(A)/Length(B));
     75 }
     76 
     77 double Cross(Vector A,Vector B)   // 叉积
     78 {
     79     return A.x*B.y-A.y*B.x;
     80 }
     81 
     82 double Area(Point A,Point B,Point C)
     83 {
     84     return Cross(B-A,C-A);
     85 }
     86 Vector Rotate(Vector A,double rad)   //向量的逆时针旋转
     87 {
     88     return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
     89 
     90 }
     91 
     92 //调用前确保两条直线相交。当且仅当Cross(v,w)非零。
     93 Point GetLineIntersection(Point P,Vector v, Point Q,Vector w)   //计算两条直线P+tv和Q+tw的交点
     94 {
     95     Vector u=P-Q;
     96     double t=Cross(w,u)/Cross(v,w);
     97     return P+v*t;
     98 }
     99 
    100 //线段规范相交的充要条件是:每条线段的两个端点都在另一条线段的两侧(两侧指叉积的符号不同)
    101 bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)  //线段相交判定
    102 {
    103     double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1),
    104            c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);
    105     return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
    106 }
    107 // 判断一个点是否在一条线段(不包含端点)
    108 bool OnSegment(Point p, Point a1, Point a2)
    109 {
    110     return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
    111 }
    112 
    113 double DistanceToLine(Point P,Point A,Point B) //判断点到直线的距离(两点式)
    114 {
    115     Vector v1=B-A,v2=P-A;
    116     return fabs(Cross(v1,v2))/Length(v1);
    117 }
    118 
    119 double DistanceToSegment(Point P,Point A,Point B) //判断点到线段的距离
    120 {
    121     if(A==B) return Length(P-A);
    122     Vector v1=B-A,v2=P-A,v3=P-B;
    123     if(dcmp(Dot(v1,v2))<0)
    124         return Length(v2);
    125     else if(dcmp(Dot(v1,v3))>0)
    126         return Length(v3);
    127     else
    128         return fabs(Cross(v1,v2))/Length(v1);
    129 }
    130 
    131 double Min,Max;
    132 Point P[60],Q[60];
    133 
    134 void Update(Point P,Point A,Point B) //更新最小最大距离
    135 {
    136     Min=min(Min,DistanceToSegment(P,A,B));
    137     Max=max(Max,Length(P-A));
    138     Max=max(Max,Length(P-B));
    139 }
    140 
    141 int main()
    142 {
    143     int T,A,B,i,j;
    144     int icase=1;
    145     scanf("%d",&T);
    146     while(T--)
    147     {
    148         scanf("%d %d",&A,&B);
    149         for(i=0; i<A; i++)
    150             scanf("%lf %lf",&P[i].x,&P[i].y);
    151         for(i=0; i<B; i++)
    152             scanf("%lf %lf",&Q[i].x,&Q[i].y);
    153         double LenA=0,LenB=0;
    154         for(i=0; i<A-1; i++)
    155             LenA+=Length(P[i+1]-P[i]);
    156         for(i=0; i<B-1; i++)
    157             LenB+=Length(Q[i+1]-Q[i]);
    158         int Sa=0,Sb=0;//为刚经过的拐点的编号;
    159         Point Pa=P[0],Pb=Q[0];
    160         Min=inf,Max=-inf;
    161         while(Sa<A-1&&Sb<B-1)
    162         {
    163             double La=Length(P[Sa+1]-Pa);//甲到下一个拐点的距离
    164             double Lb=Length(Q[Sb+1]-Pb);//乙到下一个拐点的距离
    165             double T=min(La/LenA,Lb/LenB);//取合适的单位,让甲乙的速度分别为LenA,LenB
    166             Vector va=(P[Sa+1]-Pa)/La*T*LenA;
    167             Vector vb=(Q[Sb+1]-Pb)/Lb*T*LenB;
    168             Update(Pa,Pb,Pb+vb-va);
    169             Pa=Pa+va;
    170             Pb=Pb+vb;
    171             if(Pa==P[Sa+1]) Sa++;
    172             if(Pb==Q[Sb+1]) Sb++;
    173         }
    174         printf("Case %d: %.0lf
    ",icase++, Max-Min);
    175     }
    176     return 0;
    177 }
    View Code
  • 相关阅读:
    特殊类
    Statement和PrepareStatement有什么区别?
    关于${pageContext.request.contextPath }对于工程中的那个目录
    IDEA JSP中报错cannot resolve method println的解决方案
    关于${pageContext.request.contextPath}的理解
    IDEA中引用不到HttpServlet的解决方案
    Serializable接口的意义和用法
    idea Cannot resolve method (最新2020解决办法)
    IDEA Artifacts:Error during artifact deployment问题解决(狂神SSM整合里,报404错误方案)
    IDEA设置自动导入包方法
  • 原文地址:https://www.cnblogs.com/ITUPC/p/4868707.html
Copyright © 2020-2023  润新知