• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
LyonLys
愿意在角落唱沙哑的歌 再大声也都是给你 请用心听 不要说话 Contact me via E-mail: lyon.lys@gmail.com
博客园    首页    新随笔    联系   管理    订阅  订阅

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

posted @ 2013-04-29 21:50  LyonLys  阅读(308)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3