UVA11796:计算几何

UVA11796

题解

  • 参考蓝书上的代码。
  • 狗的速度未知,因为同时到达,设时间为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;
}

猜你喜欢

转载自blog.csdn.net/weixin_42264485/article/details/89036615