zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    ionic之样式bar-assertive
    (?m) 可以让.去匹配换行
    perl 正则前导字符
    ionic之样式bar-energized
    ionic之样式bar-balanced
    ionic之样式bar-calm
    perl /m
    sort_buffer_size:
    Filter plugins ? mutate:
    Codec plugins ? multiline
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4029917.html
Copyright © 2011-2022 走看看