UVA11796 Dog Distance

题意

PDF

分析

问题可以转化为小问题,即两条狗分别在线段上运动。

然后用相对运动知识可以认为甲不动,乙在线段上运动。

小问题就转化为点到线段的最小或最大距离。

时间复杂度\(O(I \times (A+B))\)

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
    rg T data=0;
    rg int w=1;
    rg char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data*w;
}
template<class T>T read(T&x)
{
    return x=read<T>();
}
using namespace std;
typedef long long ll;

co double eps=1e-10;
int dcmp(double x)
{
    if(fabs(x)<eps)
        return 0;
    else
        return x<0?-1:1;
}

struct Point
{
    double x,y;
    Point(double x=0,double y=0)
    :x(x),y(y){}
    
    bool operator<(co Point&rhs)co
    {
        return x<rhs.x||(x==rhs.x&&y<rhs.y);
    }
    
    bool operator==(co Point&rhs)co
    {
        return dcmp(x-rhs.x)==0&&dcmp(y-rhs.y)==0;
    }
};
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);
}

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 Angle(Vector A,Vector B)
{
    return acos(Dot(A,B)/Length(A)/Length(B));
}

double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}

double Area2(Point A,Point B,Point C)
{
    return Cross(B-A,C-A);
}

Vector Rotate(Vector A,double rad)
{
    return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}

Vector Normal(Vector A)
{
    double L=Length(A);
    return Vector(-A.y/L,A.x/L);
}

Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)
{
    Vector u=P-Q;
    double t=Cross(w,u)/Cross(v,w);
    return P+v*t;
}

double DistanceToLine(Point P,Point A,Point B)
{
    Vector v1=B-A,v2=P-A;
    return fabs(Cross(v1,v2))/Length(v1);
}

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);
    if(dcmp(Dot(v1,v3))>0)
        return Length(v3);
    return DistanceToLine(P,A,B);
}

Point GetLineProjection(Point P,Point A,Point B)
{
    Vector v=B-A;
    return A+v*(Dot(v,P-A)/Dot(v,v));
}

bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
{
    double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
            c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
    return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
}

bool OnSegment(Point p,Point a1,Point a2)
{
    return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;
}

double PolygonArea(Point*p,int n)
{
    double area=0;
    for(int i=1;i<n-1;++i)
        area+=Cross(p[i]-p[0],p[i+1]-p[0]);
    return area/2;
}

co int N=50;
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));
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int T=read<int>();
    for(int kase=1;kase<=T;++kase)
    {
        read(A);read(B);
        for(int i=0;i<A;++i)
        {
            read(P[i].x);read(P[i].y);
        }
        for(int i=0;i<B;++i)
        {
            read(Q[i].x);read(Q[i].y);
        }
        
        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==P[Sb+1])
                ++Sb;
        }
        printf("Case %d: %.0lf\n",kase,Max-Min);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/10125842.html
Dog