题解
- 参考蓝书上的代码。
- 狗的速度未知,因为同时到达,设时间为T,那么T = lena / va = lenb / vb,假设T = 1,那么可以得到速度等于路程。
- 在两条线段上同时匀速运动,那么相对最小的距离怎么求呢?因为速度是相对的,我们可以假设一只狗不动,另一只狗以相对的速度在运动。那么问题转化为点到直线的最小和最大距离。
- updata(p1,p2,p2+vb-va)这句话不好理解。va,vb分别表示两只狗在线段上的位移量。updata表示p1到线段p2--p2+vb-va的距离。因为a静止,p2+vb-va表示b相对a的位移量。
代码
#include <bits/stdc++.h>
using namespace std;
int const N = 60;
double const eps = 1e-10;
double const inf = 1e10;
int A,B;
double lena,lenb,MAX,MIN;
int dcmp(double x){ //判断符号
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
typedef struct Point{ //点和向量
double x,y;
Point(){};
Point(double x,double y):x(x),y(y){};
Point operator - (const Point& e)const{ //减
return Point(x - e.x,y - e.y);
}
Point operator + (const Point& e)const{ //减
return Point(x + e.x,y + e.y);
}
double operator ^ (const Point& e)const{ //叉乘
return x * e.y - y * e.x;
}
Point operator * (const double& p) const{
return Point(x * p,y * p);
}
Point operator / (const double& p) const{
return Point(x / p,y / p);
}
bool operator == (const Point &e)const{
return !dcmp(x - e.x) && !dcmp(y - e.y);
}
}Vector;
Point pa[N],pb[N];
double Dot(Vector a,Vector b){
return a.x * b.x + a.y * b.y;
}
double Length(Vector A){
return sqrt(Dot(A,A));
}
double DistanceToSegment(Point p,Point a,Point b){
if(a == b) return Length(p - a);
Vector v1 = b - a, v2 = p - a, v3 = p - b;
if(dcmp(Dot(v1,v2)) < 0) return Length(v2);
else if(dcmp(Dot(v1,v3)) > 0) return Length(v3);
else return fabs(v1 ^ v2) / Length(v1);
}
void updata(Point p,Point a,Point b){ //p到线段ab的距离
MIN = min(MIN,DistanceToSegment(p,a,b));
MAX = max(MAX,Length(Vector(p - a)));
MAX = max(MAX,Length(Vector(p - b)));
}
int main(){
int T,caser = 0;
scanf("%d",&T);
while(T--){
scanf("%d%d",&A,&B);
for(int i=0;i<A;i++)
scanf("%lf%lf",&pa[i].x,&pa[i].y);
for(int i=0;i<B;i++)
scanf("%lf%lf",&pb[i].x,&pb[i].y);
lena = lenb = 0;
for(int i=0;i<A-1;i++) lena += Length(pa[i+1] - pa[i]);
for(int i=0;i<B-1;i++) lenb += Length(pb[i+1] - pb[i]);
int sa = 0, sb = 0;
Point p1 = pa[0], p2 = pb[0];
MAX = -inf, MIN = inf;
while(sa < A - 1 && sb < B - 1){
double la = Length(pa[sa+1] - p1);
double lb = Length(pb[sb+1] - p2);
double T = min(la / lena,lb / lenb);
Vector va = (pa[sa+1] - p1) / la * T * lena;
Vector vb = (pb[sb+1] - p2) / lb * T * lenb;
updata(p1,p2,p2+vb-va);
p1 = p1 + va;
p2 = p2 + vb;
if(p1 == pa[sa+1]) sa++;
if(p2 == pb[sb+1]) sb++;
}
printf("Case %d: %.0f\n",++caser,MAX - MIN);
}
return 0;
}