题意:给定两条狗的行走路线,一直两条狗同时出发同时到达,问路途中的最远和最近距离。
思路:先简化版本,如果甲乙都仅沿着两条线段向前跑,那么他们之间的最短和最长距离怎么算? 假设甲的速度向量为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 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 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 0)126 return Length(v3);127 else128 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