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

    用到了 物理的相对运动, 其实就是向量, 两个向量相减就是他们相对位移的方向


    题意:

    有甲乙两条狗分别沿着一条折线奔跑,已知它们同时从各自的起点出发,同时到达各自的终点。求整个过程中两条狗的最大距离Max与最小距离Min的差值。

    分析:

    假设甲乙的路线都是一条线段的简单情况。运动是相对的,我们假定甲不动,乙相对甲的运动也是匀速直线运动。所以就将问题转化成了点到直线的最小和最大距离。

    甲或乙每到达一个拐点所对应的时刻称作“关键点”,那么没两个关键点之间的运动都可看做上面分析的简单情况。我们只要及时更新甲乙的位置即可。

    LenA和LenB分别是两条路线的总长,因为运动时间相同,不妨设二者的运动速度为LenA和LenB,这样总时间为1

    #include <cstdio>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    struct Point
    {
    	double x, y;
    	Point (double x = 0, double y = 0) : x(x), y(y) { } //构造函数, 方便代码书写
    };
    typedef Point myvector;
    Point a[60], b[60];
    double Max, Min;
    
    // 向量 + 向量 = 向量
    myvector operator + (myvector A, myvector B) { return myvector(A.x + B.x, A.y + B.y); }
    // 点 - 点 = 向量
    myvector operator - (Point A, Point B) { return myvector(A.x - B.x, A.y - B.y); }
    //向量 * 数 = 向量
    myvector operator * (myvector A, double p) { return myvector(A.x * p, A.y * p); }
    //向量/数 = 向量
    myvector operator / (myvector A, double p) { return myvector(A.x / p, A.y / p); }
    // 小于号
    bool operator < (const Point & a, const Point & b)
    {
    
    	if (a.x == b.x) return a.y < b.y;
    	return a.x < b.x;
    }
    //比较
    const double eps = 1e-10;
    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;
    }
    // 计算向量 A B 的点积, A*B = |A| * |B| * cosß
    double Dot (myvector A, myvector B) { return A.x*B.x + A.y*B.y; }
    // 计算向量 A 的长度
    double Length (myvector A) { return sqrt (Dot(A, A)); }
    // 计算向量 A,B 的夹角,是cos 有公式
    double Angle (myvector A, myvector B)
    { return acos(Dot(A, B) / Length(A) / Length(B)); }
    
    // 计算叉积,AxB = |A| * |B| * sinß, 得到的是与这两个向量垂直的向量
    double Cross(myvector A, myvector B) { return A.x * B.y - A.y * B.x; }
    // 点到线段的距离, 有两种可能, 一种点在线段上方, 这时候算垂直, 不在线段上方;
    double DistanceToSegment(Point P, Point A, Point B)
    {
    	if( A == B) return Length(P-A); //如果线段是一个点
    	myvector 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);
    }
    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));
    }
    
    int main()
    {
    	int T, m, n, Case = 0, i;
    	cin >> T;
    	while(T--)
    	{
    		double LenA = 0.0, LenB = 0.0;
    		cin >> m >> n;
    		for(i = 0; i < m; i++)
    		{
    			cin >> a[i].x >> a[i].y;
    			if(i > 0)
    				LenA += Length(a[i]-a[i-1]);//计算出来A的路程总长,设1s到达,则又是他的速度
    		}
    
    		for(i = 0; i < n; i++)
    		{
    			cin >> b[i].x >> b[i].y;
    			if(i > 0)
    				LenB += Length(b[i]-b[i-1]);
    		}
    
    		int Sa = 0, Sb = 0;        //A B当前端点的编号
            Point Pa = a[0], Pb = b[0];
            Min = 1e9, Max = -1e9;
            while(Sa < m - 1 && Sb < n - 1)
            {
                double La = Length(a[Sa+1] - Pa);    //AB分别到下一拐点的距离
                double Lb = Length(b[Sb+1] - Pb);
                double t = min(La / LenA, Lb / LenB);
                myvector Va = ((a[Sa+1] - Pa) / La) //这段时间的单位向量
                								* t * LenA; //这段时间内单位向量所走向量
                myvector Vb = ((b[Sb+1] - Pb) / Lb) * t * LenB;
                //printf("Va %f %f   Vb %f %f
    ", Va.x, Va.y, Vb.x,  Vb.y);
                update(Pa, Pb, Pb + Vb - Va);
                Pa = Pa + Va;
                Pb = Pb + Vb;
                if(Pa == a[Sa+1])    Sa++;
                if(Pb == b[Sb+1])    Sb++;
            }
    
            printf("Case %d: %.0lf
    ", ++Case, Max - Min);
    	}
    }


    www.cnblogs.com/tenlee
  • 相关阅读:
    SpringMVC拦截器
    SpringMVC异常
    SpringMVC文件上传
    SpringMVC返回值类型
    JVM字节码
    使用Apache JMeter进行测试
    Tomcat优化
    垃圾收集器
    GC常见算法
    VisualVM远程连接Tomcat
  • 原文地址:https://www.cnblogs.com/tenlee/p/4420121.html
Copyright © 2011-2022 走看看