zoukankan      html  css  js  c++  java
  • UVA-11796 Dog Distance

    题意:两只狗,Ranga和Banga,分别在两条不同的路径上奔跑。他们每个人都花费了T秒在不同的速度下,Ranga用一个均匀速度Rm/s奔跑,Banga用一个均匀速度Sm/s奔跑。两只狗在在起点和终点的时间是相同的。让我们定义D(t)为两只狗在t时相距的距离。狗的距离定义为他们在他们的旅程的最大距离和最小距离之差。(Dog Distance = {max(D(a)) 0 <= a <= T} - {min(D(b)) 0 <= b <= T})。给出两只狗的路径,你的目的是去寻找两只狗的距离。每条路径都有N个点组成。

    分析:可以认为甲静止不动,乙自己沿着直线走,问题转化为求点到线段的最小距离或最大距离。这道题没有指明速度是多少,我们可以假定速度为整段路程,那么T = min(La / LenA, Lb / LenB),我们把问题拆分成简化版的问题,每次计算他俩谁先到达拐点,那么在这个时间点之间的问题就是我们刚才讨论过的"简化版"。Vector Va = (P[Sa + 1] - Pa) / La * T * LenA。先求出位移的单位向量,即(位移向量 / 位移长度 * 时间 * 速度),就可以得到在T时的位移向量,然后我们更新min和max,然后使用update(Pa, Pb, Pb + Vb - Va),这里假定a点静止不动,b点在动,那么Pb + Vb - Va就是b点相对于a移动的距离,然后求解a点到这条线段的距离即可。可以分为3种情况,如下
    ,两边是最大的距离,中间是最短距离。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    const int N = 60;
    const double eps = 1e-6;
    
    struct Point
    {
    	double x, y;
    	Point(double x = 0, double y = 0) : x(x), y(y) {}
    };
    
    typedef Point Vector;
    Vector operator+(Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
    Vector operator-(Point A, Point B) { return Vector(A.x - B.x, A.y - B.y); }
    Vector operator*(Vector A, double p) { return Vector(A.x * p, A.y * p); }
    Vector operator/(Vector A, double p) { return Vector(A.x / p, A.y / p); }
    bool operator<(const Point& a, const Point& b)
    {
    	return a.x < b.x || (a.x == b.x && a.y < b.y);
    }
    
    int dcmp(double x)
    {
    	if (fabs(x) < eps) return 0;
    	else return x < 0 ? -1 : 1;
    }
    
    bool operator==(const Point& a, const Point& b)
    {
    	return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
    }
    
    double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; }
    double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; }
    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(Cross(v1, v2)) / Length(v1);
    }
    
    //第一条路径的点个数,第二条路径的点个数
    int A, B;
    //第一条路径的点,第二条路径的点
    Point P[N], Q[N];
    double Min, Max;
    
    void update(Point P, Point A, Point B)
    {
    	Min = min(Min, DistanceToSegment(P, A, B));
    	Max = max(Max, Length(P - A));
    	Max = max(Max, Length(P - B));
    }
    
    Point read_point()
    {
    	double x, y;
    	scanf("%lf%lf", &x, &y);
    	return Point(x, y);
    }
    
    int main()
    {	
    	int t;
    	scanf("%d", &t);
    
    	int c = 0;
    	while (t--)
    	{
    		//第一条路径的点个数,第二条路径的点个数
    		scanf("%d%d", &A, &B);
    		for (int i = 0; i < A; ++i) P[i] = read_point();
    		for (int i = 0; i < B; ++i) Q[i] = read_point();
    
    		double LenA = 0, LenB = 0;
    		for (int i = 0; i < A - 1; ++i) LenA += Length(P[i + 1] - P[i]);
    		for (int i = 0; i < B - 1; ++i) LenB += Length(Q[i + 1] - Q[i]);
    
    		//拐点编号
    		int Sa = 0, Sb = 0;
    		//现处于的点
    		Point Pa = P[0], Pb = Q[0];
    		Min = 1e9, Max = -1e9;
    
    		while (Sa < A - 1 && Sb < B - 1)
    		{
    			double La = Length(P[Sa + 1] - Pa);
    			double Lb = Length(Q[Sb + 1] - Pb);
    			//到达拐点的最短时间
    			double T = min(La / LenA, Lb / LenB);
    			//位移向量
    			Vector Va = (P[Sa + 1] - Pa) / La * T * LenA;
    			Vector Vb = (Q[Sb + 1] - Pb) / Lb * T * LenB;
    			update(Pa, Pb, Pb + Vb - Va);
    			Pa = Pa + Va;
    			Pb = Pb + Vb;
    			if (Pa == P[Sa + 1]) ++Sa;
    			if (Pb == Q[Sb + 1]) ++Sb;
    		}
    		printf("Case %d: %.0lf
    ", ++c, Max - Min);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    Windows2003 Webshell默认权限
    Windows安装Centos7双系统后Windows启动项消失
    GCC编译流程及常用编辑命令
    swoole的websockte例子
    PhpStorm 增加Swoole智能提示
    Centos7/RHEL 7 配置静态路由
    webpack介绍和使用
    Webpack中的sourcemap以及如何在生产和开发环境中合理的设置
    什么是 PWA
    php实现excel单元格合并,字体加粗居中等操作
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13261246.html
Copyright © 2011-2022 走看看