• 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
  • 相关阅读:
    【SpringCloud】Nacos集群部署(Centos平台)
    ASTreeView 1.5.3发布(ASP.NET树控件)
    ASTreeView 1.4.0发布(ASP.NET树控件)
    ASTreeView 1.3.0发布(ASP.NET树控件)
    ASTreeView 1.1.1发布(ASP.NET树控件)
    More Effective C++ 学习笔记_限制一个类实例化的对象个数
    3D数学基础:图形与游戏开发__向量的矩阵转换
    Firefox3,IE6,IE7,IE8上传图片预览
    身份证验证
    无数据库日志文件恢复数据库方法两则(转)
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5524470.html
Copyright © 2020-2023  润新知