An Easy Physics Problem HDU - 5572
An Easy Physics Problem HDU - 5572
题目大意:
在平面上有一个圆柱和一个可以无视体积的小球,给定圆柱的坐标和半径。给定小球\(A\)的初始位置和速度矢量。
问小球是否可以到达\(B\)。
思路
分两种情况讨论
-
小球\(A\)通过速度矢量\(v\)可以直接到达\(B\)
首先判断\(A\),\(B\)共线。
其次,考虑特殊情况,直线\(AB\)穿过圆\(O\),但\(|AF|>|AB|\),
-
小球\(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")); } }