poj3924

题目:给定一个起点(xw1, yw1),直线经过(xw2, yw2),速度为vw无限运动的点,还有一个起点(xt1, yt1),终点(xt2, yt2),并且在以vt速度在两者往返运动,求两者在运动中的最近距离。。如果小于给定的dl,输出Dangerous,大于du输出Miss,否则输出perfect。。

思路:

      ACM2008北京赛区的计算几何题,也是dyf神犇violet系列的一道题。。

      思路不是很难,以xw点为参考系,那么题目就变成了求某个点及一些折线的最近距离。。

      而且这些折线可以分成两组平行线段,每组可以分别求。

      至于怎么求,可以用dyf神犇的数学方法。。(可能我太弱了,写完后一直错挑了半天就直接弃疗了)

      我最后用的是直接三分线段,写起来好写一点。。

      有什么不明白的可以看dyf博客。。写的很清楚。。

code:

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<string>
  8 #include<map>
  9 #include<set>
 10 #include<vector>
 11 #include<queue>
 12 #include<stack>
 13 #include<ctime>
 14 #include<utility>
 15 #define M0(x)  memset(x, 0, sizeof(x))
 16 #define eps 1e-8
 17 #define pi acos(-1.0)
 18 using namespace std;
 19 inline int sgn(const double& x){
 20     return (x > eps) - (x < -eps);
 21 }
 22 struct point{
 23        double x, y;
 24        point(){}
 25        point(double _x, double _y):x(_x), y(_y){}
 26        void input(){
 27             scanf("%lf%lf", &x, &y);
 28        }
 29        double len()const{
 30             return sqrt(x * x + y * y);
 31        }
 32        point trunc(double l)const{
 33             double r = l / len();
 34             return point(r * x, r * y);
 35        }
 36        point rotate_left()const{
 37             return point(-y, x);
 38        }
 39        point operator-(const point& p1)const{
 40             return point(x - p1.x, y - p1.y);
 41        }
 42        point operator+(const point& p1)const{
 43             return point(x + p1.x, y + p1.y);         
 44        }
 45        bool operator==(const point& p1)const{
 46             return sgn(x - p1.x) == 0 && sgn(y - p1.y) == 0; 
 47        }
 48        double operator*(const point& p1)const{
 49              return x * p1.y - y * p1.x;
 50        }
 51        double operator^(const point& p1)const{
 52              return x * p1.x + y * p1.y;
 53        }
 54        point operator*(const double& l) const{
 55              return point(x *l , y * l);      
 56        }
 57        void out(){
 58             printf("%.2f %.2f
", x, y);     
 59        }
 60 } p[10], p2[10], v[10], zero(0, 0);
 61 double di, du, vnow;
 62 
 63 double get_distance(const point &p, const point &p1, const point &p2){
 64      if (sgn((p2 - p1) ^ (p - p1)) <= 0) return (p - p1).len();
 65      if (sgn((p1 - p2) ^ (p - p2)) <= 0) return (p - p2).len();
 66      return fabs((p1 - p) * (p2 - p)) / (p1 - p2).len();
 67 }
 68 
 69 void init(){
 70      p2[0].input(), scanf("%lf", &vnow);
 71      v[0] =(p2[0]-p[0]).trunc(vnow);
 72      p[1].input(), p2[1].input(), scanf("%lf", &vnow);
 73      v[1] = (p2[1] - p[1]).trunc(vnow);
 74      p[1] = p[1] - p[0], p2[1] = p2[1] - p[0]; 
 75      scanf("%lf%lf", &di, &du);
 76 }
 77 
 78 double gao(const point& p0,const point& p1, const point& p2){
 79      int l = 0, r = 0x3fffffff, ui, l1, r1;
 80      point v = p2 - p0;
 81      point p00, p11;
 82      double dis1, dis2, ans = 1e20;
 83      while (l + 1 < r){
 84             if (l + 2 >= r){
 85                    ans = min(ans, get_distance(zero, p0 + v * l, p1 + v * l));
 86                    ans = min(ans, get_distance(zero, p0 + v * r, p1 + v * r));
 87                    if (l + 2 == r)
 88                        ans = min(ans, get_distance(zero, p0 + v * (l+1), p1 + v * (l+1)));
 89                    break;
 90             }
 91             ui = (r - l + 1) / 3;
 92             l1 = l + ui, r1 = r - ui;
 93             dis1 = get_distance(zero, p0 + v * l1, p1 + v * l1);
 94             dis2 = get_distance(zero, p0 + v * r1, p1 + v * r1);
 95             if (dis1 < dis2) r = r1;
 96             else l = l1;
 97                   
 98      }
 99      return ans;
100 }
101 
102 void solve(){
103      point v1 = v[1] - v[0], v2 = (v[1] + v[0]) * (-1);
104      double t = (p2[1] - p[1]).len() / vnow;
105      point p0 = p[1], p1 = p0 + v1 * t, p3 = p1 + v2 * t, p4 = p3 + v1 * t;
106 //     p0.out(), p1.out(), p3.out(), p4.out();
107      double ans = gao(p0, p1, p3);
108      ans = min(gao(p1, p3, p4), ans); 
109      if (ans < di - eps) puts("Dangerous");
110      else if (ans > du + eps) puts("Miss");
111      else puts("Perfect");
112 }
113 
114 int main(){
115     while (scanf("%lf%lf", &p[0].x, &p[0].y) != EOF){
116         init();
117         solve();
118     }
119     return 0;
120 }
View Code
原文地址:https://www.cnblogs.com/yzcstc/p/4029917.html