• uva 11796 Dog Distance (几何+模拟)


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

      一道几何模拟题。题意是,两只狗分别在两条折线上运动,已知运动轨迹,以及他们是同时到达折线的末端的。问题是,要求他们运动过程中最大距离与最小距离的差是多少。

      表示我十分欣赏这题的做法。估计是我太饿了的缘故,居然看了天都没有想到可以将同时运动转化为相对运动,然后用静态的方法来解决这个动态的问题。如果假设A是不动的,那么这时候,我们只要搞到相对位移就可以解决问题了。

    代码如下:

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <set>
      5 #include <vector>
      6 #include <iostream>
      7 #include <algorithm>
      8 
      9 using namespace std;
     10 
     11 #define REP(i, n) for (int i = 0; i < (n); i++)
     12 
     13 struct Point {
     14     double x, y;
     15     Point() {}
     16     Point(double x, double y) : x(x), y(y) {}
     17 } ;
     18 template<class T> T sqr(T x) { return x * x;}
     19 double ptDis(Point a, Point b) { return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));}
     20 
     21 // basic calculations
     22 typedef Point Vec;
     23 Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
     24 Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
     25 Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
     26 Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);}
     27 
     28 const double eps = 1e-8;
     29 int sgn(double x) { return fabs(x) < eps ? 0 : (x < 0 ? -1 : 1);}
     30 bool operator < (Point a, Point b) { return a.x < b.x || (a.x == b.x && a.y < b.y);}
     31 bool operator == (Point a, Point b) { return sgn(a.x - b.x) == 0 && sgn(a.y - b.y) == 0;}
     32 
     33 double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
     34 double vecLen(Vec x) { return sqrt(sqr(x.x) + sqr(x.y));}
     35 double angle(Vec a, Vec b) { return acos(dotDet(a, b) / vecLen(a) / vecLen(b));}
     36 double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
     37 double triArea(Point a, Point b, Point c) { return fabs(crossDet(b - a, c - a));}
     38 Vec rotate(Vec x, double rad) { return Vec(x.x * cos(rad) - x.y * sin(rad), x.x * sin(rad) + x.y * cos(rad));}
     39 Vec normal(Vec x) {
     40     double len = vecLen(x);
     41     return Vec(- x.y / len, x.x / len);
     42 }
     43 
     44 struct Line {
     45     Point s, t;
     46     Line() {}
     47     Line(Point s, Point t) : s(s), t(t) {}
     48 } ;
     49 typedef Line Seg;
     50 
     51 bool onSeg(Point x, Point a, Point b) { return sgn(crossDet(a - x, b - x)) == 0 && sgn(dotDet(a - x, b - x)) < 0;}
     52 bool onSeg(Point x, Seg s) { return onSeg(x, s.s, s.t);}
     53 // 0 : not intersect
     54 // 1 : proper intersect
     55 // 2 : improper intersect
     56 int segIntersect(Point a, Point c, Point b, Point d) {
     57     Vec v1 = b - a, v2 = c - b, v3 = d - c, v4 = a - d;
     58     int a_bc = sgn(crossDet(v1, v2));
     59     int b_cd = sgn(crossDet(v2, v3));
     60     int c_da = sgn(crossDet(v3, v4));
     61     int d_ab = sgn(crossDet(v4, v1));
     62     if (a_bc * c_da > 0 && b_cd * d_ab > 0) return 1;
     63     if (onSeg(b, a, c) && c_da) return 2;
     64     if (onSeg(c, b, d) && d_ab) return 2;
     65     if (onSeg(d, c, a) && a_bc) return 2;
     66     if (onSeg(a, d, b) && b_cd) return 2;
     67     return 0;
     68 }
     69 int segIntersect(Seg a, Seg b) { return segIntersect(a.s, a.t, b.s, b.t);}
     70 
     71 // point of the intersection of 2 lines
     72 Point lineIntersect(Point P, Vec v, Point Q, Vec w) {
     73     Vec u = P - Q;
     74     double t = crossDet(w, u) / crossDet(v, w);
     75     return P + v * t;
     76 }
     77 Point lineIntersect(Line a, Line b) { return lineIntersect(a.s, a.t - a.s, b.s, b.t - b.s);}
     78 
     79 // directed distance
     80 double pt2Line(Point x, Point a, Point b) {
     81     Vec v1 = b - a, v2 = x - a;
     82     return crossDet(v1, v2) / vecLen(v1);
     83 }
     84 double pt2Line(Point x, Line L) { return pt2Line(x, L.s, L.t);}
     85 
     86 double pt2Seg(Point x, Point a, Point b) {
     87     if (a == b) return vecLen(x - a);
     88     Vec v1 = b - a, v2 = x - a, v3 = x - b;
     89     if (sgn(dotDet(v1, v2)) < 0) return vecLen(v2);
     90     if (sgn(dotDet(v1, v3)) > 0) return vecLen(v3);
     91     return fabs(crossDet(v1, v2)) / vecLen(v1);
     92 }
     93 double pt2Seg(Point x, Seg s) { return pt2Seg(x, s.s, s.t);}
     94 
     95 struct Poly {
     96     vector<Point> pt;
     97     Poly() {}
     98     Poly(vector<Point> pt) : pt(pt) {}
     99     double area() {
    100         double ret = 0.0;
    101         int sz = pt.size();
    102         for (int i = 1; i < sz; i++) {
    103             ret += crossDet(pt[i], pt[i - 1]);
    104         }
    105         return fabs(ret / 2.0);
    106     }
    107 } ;
    108 
    109 /****************** template above *******************/
    110 
    111 const int N = 55;
    112 Point A[N], B[N];
    113 
    114 int main() {
    115 //    freopen("in", "r", stdin);
    116     int a, b, T;
    117     cin >> T;
    118     for (int cas = 1; cas <= T; cas++) {
    119         cin >> a >> b;
    120         for (int i = 0; i < a; i++) cin >> A[i].x >> A[i].y;
    121         for (int i = 0; i < b; i++) cin >> B[i].x >> B[i].y;
    122         double lenA = 0.0, lenB = 0.0;
    123         for (int i = 1; i < a; i++) lenA += ptDis(A[i - 1], A[i]);
    124         for (int i = 1; i < b; i++) lenB += ptDis(B[i - 1], B[i]);
    125         Point posA = A[0], posB = B[0];
    126         double mn = 1e100, mx = 0.0;
    127         int idA = 1, idB = 1;
    128         while (idA < a && idB < b) {
    129             double disA = ptDis(posA, A[idA]);
    130             double disB = ptDis(posB, B[idB]);
    131             double minTime = min(disA / lenA, disB / lenB);
    132             Vec dirA = (A[idA] - posA) * minTime * lenA / disA; // displacement of A
    133             Vec dirB = (B[idB] - posB) * minTime * lenB / disB; // displacement of B
    134             mn = min(mn, pt2Seg(posA, posB, posB + dirB - dirA)); // see A as static, so it is just that B is moving
    135             mx = max(mx, max(ptDis(posA, posB), ptDis(posA, posB + dirB - dirA)));
    136             posA = posA + dirA;
    137             posB = posB + dirB;
    138             if (posA == A[idA]) idA++;
    139             if (posB == B[idB]) idB++;
    140         }
    141         printf("Case %d: %.f\n", cas, mx - mn);
    142     }
    143     return 0;
    144 }

    ——written by Lyon

  • 相关阅读:
    Socket网络编程
    android开发常用颜色
    eclipse使用技巧以及开发安卓程序过程中遇到的问题
    XML文件中的常用属性
    将博客园的文本编辑栏属性变成可以粘贴
    显示单位px、dip、pt以及sp
    WIN32 API IP地址转换
    常用win32api函数
    win32—GrafMenu的CreateBitmapIndirect创建失败的问题
    #pragam 使用方法
  • 原文地址:https://www.cnblogs.com/LyonLys/p/uva_11796_Lyon.html
Copyright © 2020-2023  润新知