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
  • 相关阅读:
    ActiveSync合作关系对话框的配置
    WINCE对象存储区(object store)
    Wince 隐藏TASKBAR的方法
    Wince输入法换肤换语言机制
    poj 3080 Blue Jeans 解题报告
    codeforces A. Vasily the Bear and Triangle 解题报告
    hdu 1050 Moving Tables 解题报告
    hdu 1113 Word Amalgamation 解题报告
    codeforces A. IQ Test 解题报告
    poj 1007 DNA Sorting 解题报告
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4029917.html
Copyright © 2011-2022 走看看