zoukankan      html  css  js  c++  java
  • UVA_11796_Dog_Distance_(计算几何)

    描述


    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2896

    两只狗分别沿着各自的折线匀速跑,同时出发,同时到达.求其间它们两的最大距离和最小距离之差.

    11796
    Dog Distance
    Two dogs, Ranga and Banga, are running randomly following two
    different paths. They both run for T seconds with different speeds.
    Ranga runs with a constant speed of R m/s, whereas Banga runs
    with a constant speed of S m/s. Both the dogs start and stop at the
    same time. Let D(t) be the distance between the two dogs at time
    t.
    The dog distance is equal to the difference between the maximum
    and the minimum distance between the two dogs in their whole jour-
    ney.
    Mathematically,
    Dog Distance = {max(D(a)) 0 ≤ a ≤ T } − {min(D(b)) 0 ≤ b ≤ T }
    Given the paths of the two dogs, your job is to find the dog distance.
    Each path will be represented using N points, (P 1 P 2 P 3 . . . P N ). The dog following this path will
    start from P 1 and follow the line joining with P 2 , and then it will follow the line joining P 2 -P 3 , then
    P 3 -P 4 and so on until it reaches P n .
    Input
    Input starts with an integer I (I ≤ 1000), the number of test cases.
    Each test case starts with 2 positive integers A (2 ≤ A ≤ 50), B (2 ≤ B ≤ 50). The next line
    contains the coordinates of A points with the format X 1 Y 1 X 2 Y 2 . . . X A Y A , (0 ≤ X i , Y i ≤ 1000).
    These points indicate the path taken by Ranga. The next line contains B points in the same format.
    These points indicate the path taken by Banga. All distance units are given in meters and consecutive
    points are distinct. All the given coordinates are integers.
    Note that the values of T , R and S are unknown to us.
    Output
    For each case, output the case number first. Then output the dog distance rounded to the nearest
    integer. Look at the samples for exact format.
    Sample Input
    2
    2 2
    0 0
    0 1
    3 2
    635
    117
    10 0
    10 1
    187 241 269 308 254
    663 760 413
    Sample Output
    Case 1: 0
    Case 2: 404

    分析


    先考虑简单的情况:两条狗都在线段上跑.由于运动是相对的,可以以其中一条狗为参考系,那么另一条狗以v2-v1(矢量差)的速度相对于狗#1运动,那么最大最小距离就是点到线段的距离了.

    再考虑复杂的情况:可以把复杂情况分解为多个上述的简单情况.用pa,pb记录两条狗当前的位置,sa,sb表示它们刚经过各自的第sa和第sb个折点,计算它们俩谁先到达下一个折点,从当前时间到它到达下一个折点的时间,在这段时间里就是简单情况,求解完之后再更新pa,pb,如果需要的话还要更新sa,sb.由于每次至少经过一个折点,所以最多进行A+B次处理.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn=60;
     5 const double INF=1e10,eps=1e-8;
     6 
     7 int n,A,B,kase;
     8 double Max,Min;
     9 struct Point{
    10     double x,y;
    11      Point(double x=0,double y=0):x(x),y(y){}
    12 }a[maxn],b[maxn];
    13 typedef Point Vector;
    14 int dcmp(double x){
    15     if(fabs(x)<eps) return 0;
    16     return x>0?1:-1;
    17 }
    18 Vector operator + (Vector a,Vector b){ return Vector(a.x+b.x,a.y+b.y); }
    19 Vector operator - (Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y); }
    20 Vector operator * (Vector a,double p){ return Vector(a.x*p,a.y*p); }
    21 Vector operator / (Vector a,double p){ return Vector(a.x/p,a.y/p); }
    22 bool operator < (Vector a,Vector b){ return a.x<b.x||(a.x==b.x&&a.y<b.y); }
    23 bool operator == (Vector a,Vector b){ return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; }
    24 double dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }
    25 double cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }
    26 double length(Vector a){ return sqrt(dot(a,a)); }
    27 double distance_to_segment(Point p,Point a,Point b){//点到线段距离
    28     if(a==b) return length(p-a);
    29     Vector v1=b-a,v2=p-a,v3=p-b;
    30     if(dcmp(dot(v1,v2)<0)) return length(v2);
    31     if(dcmp(dot(v1,v3)>0)) return length(v3);
    32     return fabs(cross(v1,v2)/length(v1));
    33 }
    34 void update(Point p,Point a,Point b){//简单情况
    35     Min=min(Min,distance_to_segment(p,a,b));
    36     Max=max(Max,length(p-a));
    37     Max=max(Max,length(p-b));
    38 }
    39 void solve(){
    40     scanf("%d%d",&A,&B);
    41     double lena=0,lenb=0;
    42     for(int i=1;i<=A;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
    43     for(int i=1;i<=B;i++) scanf("%lf%lf",&b[i].x,&b[i].y);
    44     for(int i=1;i<A;i++) lena+=length(a[i+1]-a[i]);
    45     for(int i=1;i<B;i++) lenb+=length(b[i+1]-b[i]);
    46     Min=INF,Max=-INF;
    47     int sa=1,sb=1;
    48     Point pa=a[1],pb=b[1];
    49     while(sa<A){
    50         double la=length(a[sa+1]-pa);
    51         double lb=length(b[sb+1]-pb);//用总长来代表速度
    52         double t=min(la/lena,lb/lenb);
    53         Vector va=(a[sa+1]-pa)/la*t*lena;
    54         Vector vb=(b[sb+1]-pb)/lb*t*lenb;//两个位移向量
    55         update(pa,pb,pb+vb-va);
    56         pa=pa+va;
    57         pb=pb+vb;
    58         if(pa==a[sa+1]) sa++;
    59         if(pb==b[sb+1]) sb++;
    60     }
    61     printf("Case %d: %.0lf
    ",++kase,Max-Min);
    62 }
    63 int main(){
    64     scanf("%d",&n);
    65     while(n--) solve();
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    C++中static修饰的静态成员函数、静态数据成员
    C++友元函数、友元类
    C++异常处理
    运行时类型识别RTTI
    AD转换
    敏捷模式下的测试用例该如何存在?
    使用Postman轻松实现接口数据关联
    接口测试Mock利器-moco runner
    python测开平台使用dockerfile构建镜像
    MySQL – 用SHOW STATUS 查看MySQL服务器状态
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5524470.html
Copyright © 2011-2022 走看看