An Easy Physics Problem HDU - 5572

An Easy Physics Problem HDU - 5572

题目大意:

​ 在平面上有一个圆柱和一个可以无视体积的小球,给定圆柱的坐标和半径。给定小球\(A\)的初始位置和速度矢量。

​ 问小球是否可以到达\(B\)

思路

​ 分两种情况讨论

  1. 小球\(A\)通过速度矢量\(v\)可以直接到达\(B\)

    首先判断\(A\),\(B\)共线。

    其次,考虑特殊情况,直线\(AB\)穿过圆\(O\),但\(|AF|>|AB|\)

    1

  2. 小球\(A\)需要通过碰撞才可能到达\(B\)
    首先要求\(AV\)与圆交点为\(2\),其次,求出对称向量\(\overrightarrow{V'A'}\),并判断\(B\)是否在对称向量上。

    /**
           爆ぜろリアル!弾けろシナプス!パニッシュメント・ディス・ワールド!     
                                                                              
                             ';!!!:`                                        
                         .;%%%%$$$$%%%;.                                    
                       .;$%;.         :%;.                                  
                      `||`              :!.                                 
                     .!:                 ::                                 
                     :;                  .`.                                
                     '`                   ..                                
                     ``                   .                                 
                      ..                 ..                                 
                                         ..                                 
                             `;||!:';|%$$$%%%$$%|;'.                        
                         '|%%%%%%%%%%%%%%%%%%%%%%%%%%%%|:.                  
                       ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$|:               
                    .:!%%%%%%%%%%|!|%%%%$$&$$$%%%%%%%%%%%%%%%%|'   `:'.     
                   '!|%%%%%||%%%%%%%%%%%$&&&$%%%%%$$$%%%%%%%%%%%|'':':'.    
                 `|%%%%%%%%%%%%%$%%%%%%%$&&&&$$%%%$$$%%%%%%%%%%%%|;:::'::':`
                :%%%%%%$$%%%$$%%$%%%%%%%$&&&&&$$%%|%$%%%|!|%%%%%$!'::::;|!:'.
              .;$%%%%%$$%%%$$%%$%%%%%%%%$&&&&&$$$%%$$$%%%!!%$%%%%!::!%%%%|;'.
             .;%$%%%$$$%%%$$%%||%$$%%%%$$&&&&&&$$%%$$%%%%%%%$&&&$%$$$$%%%%|:.
             ;%%%%%$$$%%$&$%%!:!$$$%%%%$&$||&&&&$$%$$$%%%%%%$$$%%%%$$$$%%%|'
            :%%$%%$$$$%$&&$%!`'|$&$%%%%$&|`.!&&&&$%$$$%%%%%%%$%%%%%%$$$$%%%;
           `!%|%%%$&$%%$&$$|'.'|&&$%%%%$%|!'.:$&&&$$$$%%%%%%%%%%%%%%$$$$%%%|`
           ;%':%%$&&$%$&|!|'.`:|&&$%%%$$|'''``'%&&&$$$%%%%%%%%%%%%%%$&&$%%%%:
          `;' ;%%$&$%%$%;;:   .:!%$%%%$|`  ..  .!&&&$$$%%$%%%$%$$%$$%$&$%%%$;
          '' .!%$&&$$%$;`:'      `!%%%%:.... ....:$&$$$%$$%%$$$$$%$$%$&$%%%%;
          .. .;%$&&&$%|:.        ...;%|'..........'|$%%%$$%%$$&&$%$$%%%$%%%$;
              ;$$&&&$%!`        .`....'`.... ......`!%%%$$%%$&&&$$&&$!!$%%%$:
              '%$&&&&$!`.       .`........``.......`!%%$$$%$&&&&$$&&$;;$%%%%'
              '|$&&&&!``..```.  ........`|@@|'....`:|%%$$%%$&&&&$$&&$':$%%%|`
              `|$&&&&$'  .``````'''::`..........``.:%%$&$%|'`!&&$$&&%':%%%%;.
               ;$$&&|;!:`...........  .':`....`````!%$&&$%|;';&&&%|%%';%%%%:
               '%$&$:  ...................`''`...`:%%$&$$!`..!&&&$;`:;|%%%!`
                ;$&&%:.....................  .':``!%$&&$;...:$&%'`;' ;%%%%: 
                .;$&&&$:..........`'............`!%$&&&;..'%&&!     `!%%%:  
                 .':|&&&|''`..............   ...'|$&&$||$&&&|`      :|'``   
                      .!%: `|$%|!:'`.........`:!%$&&&&&$;''.       `.       
                      .:!%$%||||||%%$$$$$$$$$%$%%$$$%%:.                    
                 `!%$%%%%%%%|||||||||||%|||||||%%%%%$%%%%|:                 
              '%%%%%%%%%%%%||||||||!!|||||||||||%$$%%%%%%%%$%:              
             :%$$$%%%$%$$%||||||||!;%%||||||||%%%%%%%%%%%%%%%%|'            
             .;$%%%%$$$$$%%|||||%$$$$$%||||||||%$$%%%%%%%%%%%%%%'           
              .!%%%%%%$$%%$%%|||||;;%||||||||%$$&&|!%$$%%%$$$$$%;.          
               .!%%%%%%%%%%%%%%$%||%%%%%%%%%%%$&$$;`;%%%%%%%%$$!.           
                 :%%%%%%%%%%%%%%||%%%%%%%%%%%$$$%%%%%%%%%%%%%|'             
                    :%%%%%%%%%%$$%%%%%%%%%%%%%%%;`;%%%%%%%|:                
                   .;%%%%%%%%%%%%%%%%%%%%%%%%%%%:..:|%%%!.                  
                   '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|;:`                       
                   ;$%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%'                       
                  `|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$;                       
                  .:!%$%%%%%%%%%%%%%%%%%%%%%%%%%%%%$!.                      
                  ;!';%%%%%%%%%%%%%%%%%%%%%!:`.  `|$%'                      
                 .;%%%%%%%%%%%||%%%%%%%%%|:';|%$%%%%%;.                     
                 .!%%%%%%%%%%%%$$%%%%%%%%%%%%%%%%%%%%%'                     
                 .!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$;.                    
                 .;%%%%%%%%%%%%$%%%%%%%%%%%%%%%%%%%%%%%'                    
                  ;%$$%%%%%%%%$$$$%%%%%%%%%%%%%%%%%%%%%'                    
                 `|$&$%%%%%%$%$$$%%%%%%%%%%%%$%%%%%$&%%!`                   
                 :%$&$%%||%%%%$$%%%$%%%%%$$!:|%||%%$&$%%!`                  
    **/
    #if __cplusplus >= 201103L
    #pragma comment(linker, "/STACK:102400000,102400000")
    #pragma GCC optimize(3, "Ofast", "inline")
    #include <bits/stdc++.h>
    #else
    #include <algortmphm>
    #include <btmpset>
    #include <cmath>
    #include <iostream>
    #include <map>
    #include <string.h>
    #include <vector>
    #endif
    
    using namespace std;
    #define inf __INT_MAX__
    #define enf INT_MIN
    #define INF LLONG_MAX
    #define ENF LLONG_MIN
    
    const int MAXN = 1e5 + 10;
    const double pi = acos(-1.0);
    const double eps = 1e-7;
    typedef long long ll;
    typedef unsigned long long ull;
    #define zhengfu(x) ((x > eps) - (x < -eps))
    
    #define Dprint(...) printf("%.10f\n", ##__VA_ARGS__)
    #define Iprint(...) printf("%d\n", ##__VA_ARGS__)
    
    typedef struct point vec;
    struct point { //点的基本数据结构
        double x, y;
        double poe;
        point(double _x = 0, double _y = 0)
            : x(_x), y(_y) {
        }
        double len() //模长
        {
            return sqrt(x * x + y * y);
        }
        vec chuizhi() {
            return vec(-y, x);
        }
        double operator*(const point &i_T) const //点积
        {
            return x * i_T.x + y * i_T.y;
        }
        double operator^(const point &i_T) const //叉积
        {
            return x * i_T.y - y * i_T.x;
        }
        point operator*(double u) const {
            return point(x * u, y * u);
        }
        bool operator==(const point &i_T) const {
            return fabs(x - i_T.x) < eps && fabs(y - i_T.y) < eps;
        }
        point operator/(double u) const {
            return point(x / u, y / u);
        }
        point operator+(const point &i_T) {
            return point(x + i_T.x, y + i_T.y);
        }
        point operator-(const point &i_T) {
            return point(x - i_T.x, y - i_T.y);
        }
        friend bool operator<(point a, point b) {
            return fabs(a.y - b.y) < eps ? a.x < b.x : a.y < b.y;
        }
        void atn2() {
            poe = atan2(y, x);
        }
        friend ostream &operator<<(ostream &out, point &a) {
            //cout << a.x << ' ' << a.y;
            printf("%.8f %.8f", a.x, a.y);
            return out;
        }
        friend istream &operator>>(istream &in, point &a) {
            scanf("%lf%lf", &a.x, &a.y);
            return in;
        }
    };
    struct circle {
        point o;
        double r;
        circle(point _o = point(), double _r = 0.0)
            : r(_r), o(_o) {
        }
        point Point(double t) //圆上任意一点
        {
            return point(o.x + r * cos(t), o.y + r * sin(t));
        }
        friend istream &operator>>(istream &in, circle &a) {
            in >> a.o >> a.r;
            return in;
        }
        friend ostream &operator<<(ostream &out, circle &a) {
            out << a.o << ' ';
            printf("%.8f", a.r);
            return out;
        }
    };
    typedef struct Line Ray;
    typedef struct Line Segment; //线段Segment
    struct Line {                //直线
        point a, b;
        double poe;
        Line(point _a = point(), point _b = point())
            : a(_a), b(_b) {
        }
        vec Vec() {
            return (b - a);
        }
        double len() {
            return (b - a).len();
        }
        double x_len() {
            return b.x - (a.x - b.x) * b.y / (a.y - b.y);
        }
        bool in(point pi) {
            if (b < a)
                return ((b == pi || b < pi) && (a == pi || pi < a));
            return ((a == pi || a < pi) && (b == pi || pi < b));
        }
        bool operator==(Line i_t) {
            return (fabs(Vec() ^ i_t.Vec()) < eps && fabs(x_len() - i_t.x_len()) < eps);
        }
        bool operator<(Line i_t) {
            return fabs(poe - i_t.poe) < eps ? (Vec() ^ (i_t.b - a)) > 0 : poe < i_t.poe;
        }
        friend istream &operator>>(istream &in, Line &a) {
            cin >> a.a >> a.b;
            return in;
        }
        friend ostream &operator<<(ostream &out, Line &a) {
            out << a.a << ' ' << a.b;
            return out;
        }
        void atn2() {
            poe = atan2(b.y - a.y, b.x - a.x);
        }
    };
    point zhixian_zhixian_jiaodian(Line l1, Line l2) //两直线交点
    {
        double t = ((l1.a.x - l2.a.x) * (l2.a.y - l2.b.y) - (l1.a.y - l2.a.y) * (l2.a.x - l2.b.x)) / ((l1.a.x - l1.b.x) * (l2.a.y - l2.b.y) - (l1.a.y - l1.b.y) * (l2.a.x - l2.b.x));
        return l1.a + (l1.b - l1.a) * t;
    }
    double zhixian_yuanxin_juli(Line l, circle a) //直线到圆心的距离
    {
        return fabs((a.o - l.a) ^ (l.b - l.a)) / (l.b - l.a).len();
    }
    int zhixian_yuan_jiaodian(circle c, Line l, point &p1, point &p2) { //直线与圆交点以及个数
        if (zhixian_yuanxin_juli(l, c) > c.r)
            return 0;
        point pi = c.o;
        pi.x += l.a.y - l.b.y;
        pi.y += l.b.x - l.a.x;
        pi = zhixian_zhixian_jiaodian(Line(pi, c.o), l);
        double t = sqrt(c.r * c.r - (pi - c.o).len() * (pi - c.o).len()) / (l.a - l.b).len();
        p1 = pi + (l.b - l.a) * t;
        p2 = pi - (l.b - l.a) * t;
        return 1 + !(p1 == p2);
    }
    int xiangliang_gongxian(vec a, vec b) { //-1反向,1同向,0不共线
        if (zhengfu((a ^ b)) == 0)
            return zhengfu(a * b);
        return 0;
    }
    point touying(Line l, point c) //c投影在直线ab上的位置
    {
        vec A = l.b - l.a;
        vec B = c - l.a;
        double La = A.len();
        double Lc = (A * B) / (La * La);
        return A * Lc + l.a;
    }
    point fanshe(Line l, point c) //求c关于直线ab的对称点c'
    {
        point A = touying(l, c);
        return (A - c) * 2.0 + c;
    }
    bool solve() {
        circle c;
        point a, b;
        vec v;
        cin >> c >> a >> v >> b;
        Line l(a, a + v);
        point p1, p2;
        int tmp = zhixian_yuan_jiaodian(c, l, p1, p2);
        int f = xiangliang_gongxian(b - a, v);
        point d;
        double len1 = (p1 - a) * (p1 - a), len2 = (p2 - a) * (p2 - a);
        if (len1 > len2)
            d = p2;
        else
            d = p1;
        if (f == 1) {
            if (tmp == 2 && xiangliang_gongxian(d - a, v) == 1) {
                len1 = (d - a) * (d - a), len2 = (b - a) * (b - a);
                if (zhengfu(len1 - len2) != -1)
                    return 1;
                else
                    return 0;
            } else
                return 1;
        } else {
            if (tmp != 2)
                return 0;
            else {
                Line ll(c.o, d);
                point _a = fanshe(ll, a);
                if (xiangliang_gongxian(_a - d, b - d) == 1)
                    return 1;
                else
                    return 0;
            }
        }
    }
    int main() {
        int t;
        cin >> t;
        for (int k = 1; k <= t; k++) {
            printf("Case #%d: %s\n", k, (solve() ? "Yes" : "No"));
        }
    }
    
posted @ 2021-02-05 20:14  CrossAutomaton  阅读(90)  评论(0编辑  收藏  举报