HDU 5572--An Easy Physics Problem(射线和圆的交点)
An Easy Physics Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3845 Accepted Submission(s): 768
Problem Description
On an infinite smooth table, there's a big round fixed cylinder and a little ball whose volume can be ignored.
Currently the ball stands still at point A, then we'll give it an initial speed and a direction. If the ball hits the cylinder, it will bounce back with no energy losses.
We're just curious about whether the ball will pass point B after some time.
Currently the ball stands still at point A, then we'll give it an initial speed and a direction. If the ball hits the cylinder, it will bounce back with no energy losses.
We're just curious about whether the ball will pass point B after some time.
Input
First line contains an integer T, which indicates the number of test cases.
Every test case contains three lines.
The first line contains three integers Ox, Oy and r, indicating the center of cylinder is (Ox,Oy) and its radius is r.
The second line contains four integers Ax, Ay, Vx and Vy, indicating the coordinate of A is (Ax,Ay) and the initial direction vector is (Vx,Vy).
The last line contains two integers Bx and By, indicating the coordinate of point B is (Bx,By).
Every test case contains three lines.
The first line contains three integers Ox, Oy and r, indicating the center of cylinder is (Ox,Oy) and its radius is r.
The second line contains four integers Ax, Ay, Vx and Vy, indicating the coordinate of A is (Ax,Ay) and the initial direction vector is (Vx,Vy).
The last line contains two integers Bx and By, indicating the coordinate of point B is (Bx,By).
⋅ 1 ≤ T ≤ 100.
⋅ |Ox|,|Oy|≤ 1000.
⋅ 1 ≤ r ≤ 100.
⋅ |Ax|,|Ay|,|Bx|,|By|≤ 1000.
⋅ |Vx|,|Vy|≤ 1000.
⋅ Vx≠0 or Vy≠0.
⋅ both A and B are outside of the cylinder and they are not at same position.
Output
For every test case, you should output "Case #x: y", where x indicates the case number and counts from 1. y is "Yes" if the ball will pass point B after some time, otherwise y is "No".
Sample Input
2 0 0 1 2 2 0 1 -1 -1 0 0 1 -1 2 1 -1 1 2
Sample Output
Case #1: No Case #2: Yes
先判断射线和圆交点个数,如果小于2再看是否B在A的前进方向上,没有则NO,否则YES。如果等于2,就先找到第一个交点,将这个交点和圆心连成直线,那么A的路径关于这条直线对称,那么如果A关于此直线的对称点在圆心->B路径上,则可以相撞,否则不行。
这里有一个小问题,如果反过来求B关于此直线的对称点在圆心->A路径上,是会WA的.
这里有一个小问题,如果反过来求B关于此直线的对称点在圆心->A路径上,是会WA的.

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include<algorithm> 5 #include <cstdlib> 6 #include <cmath> 7 using namespace std; 8 const double eps = 1e-8; 9 int sgn(double x) { 10 if (fabs(x) < eps)return 0; 11 if (x < 0)return -1; 12 else return 1; 13 } 14 struct point { 15 double x, y; 16 point() {} 17 point(double x, double y) : x(x), y(y) {} 18 void input() { 19 scanf("%lf%lf", &x, &y); 20 } 21 bool operator ==(point b)const { 22 return sgn(x - b.x) == 0 && sgn(y - b.y) == 0; 23 } 24 bool operator <(point b)const { 25 return sgn(x - b.x) == 0 ? sgn(y - b.y)<0 : x<b.x; 26 } 27 point operator -(const point &b)const { //返回减去后的新点 28 return point(x - b.x, y - b.y); 29 } 30 point operator +(const point &b)const { //返回加上后的新点 31 return point(x + b.x, y + b.y); 32 } 33 point operator *(const double &k)const { //返回相乘后的新点 34 return point(x * k, y * k); 35 } 36 point operator /(const double &k)const { //返回相除后的新点 37 return point(x / k, y / k); 38 } 39 double operator ^(const point &b)const { //叉乘 40 return x*b.y - y*b.x; 41 } 42 double operator *(const point &b)const { //点乘 43 return x*b.x + y*b.y; 44 } 45 double len() { //返回长度 46 return hypot(x, y); 47 } 48 double len2() { //返回长度的平方 49 return x*x + y*y; 50 } 51 point trunc(double r) { 52 double l = len(); 53 if (!sgn(l))return *this; 54 r /= l; 55 return point(x*r, y*r); 56 } 57 }; 58 struct line { 59 point s; 60 point e; 61 line() { 62 63 } 64 line(point _s, point _e) { 65 s = _s; 66 e = _e; 67 } 68 bool operator ==(line v) { 69 return (s == v.s) && (e == v.e); 70 } 71 //返回点p在直线上的投影 72 point lineprog(point p) { 73 return s + (((e - s)*((e - s)*(p - s))) / ((e - s).len2())); 74 } 75 //返回点p关于直线的对称点 76 point symmetrypoint(point p) { 77 point q = lineprog(p); 78 return point(2 * q.x - p.x, 2 * q.y - p.y); 79 } 80 //点是否在线段上 81 bool pointonseg(point p) { 82 return sgn((p - s) ^ (e - s)) == 0 && sgn((p - s)*(p - e)) <= 0; 83 } 84 }; 85 struct circle {//圆 86 double r; //半径 87 point p; //圆心 88 void input() { 89 p.input(); 90 scanf("%lf", &r); 91 } 92 circle() { } 93 circle(point _p, double _r) { 94 p = _p; 95 r = _r; 96 } 97 circle(double x, double y, double _r) { 98 p = point(x, y); 99 r = _r; 100 } 101 //求直线和圆的交点,返回交点个数 102 int pointcrossline(line l, point &r1, point &r2) { 103 double dx = l.e.x - l.s.x, dy = l.e.y - l.s.y; 104 double A = dx*dx + dy*dy; 105 double B = 2 * dx * (l.s.x - p.x) + 2 * dy * (l.s.y - p.y); 106 double C = (l.s.x - p.x)*(l.s.x - p.x) + (l.s.y - p.y)*(l.s.y - p.y) - r*r; 107 double del = B*B - 4 * A * C; 108 if (sgn(del) < 0) return 0; 109 int cnt = 0; 110 double t1 = (-B - sqrt(del)) / (2 * A); 111 double t2 = (-B + sqrt(del)) / (2 * A); 112 if (sgn(t1) >= 0) { 113 r1 = point(l.s.x + t1 * dx, l.s.y + t1 * dy); 114 cnt++; 115 } 116 if (sgn(t2) >= 0) { 117 r2 = point(l.s.x + t2 * dx, l.s.y + t2 * dy); 118 cnt++; 119 } 120 return cnt; 121 } 122 }; 123 point A, V, B; 124 circle tc; 125 point r1, r2; 126 int main() { 127 int t, d = 1; 128 scanf("%d", &t); 129 while (t--) { 130 tc.input(); 131 A.input(); 132 V.input(); 133 B.input(); 134 int f = 0; 135 int num = tc.pointcrossline(line(A, A + V), r1, r2); 136 if (num < 2) { 137 point t = B - A; 138 if (t.trunc(1) == V.trunc(1)) f = 1; 139 else f = 0; 140 } 141 else { 142 line l = line(tc.p, r1); 143 line l1 = line(A, r1); 144 line l2 = line(r1, B); 145 point t = l.symmetrypoint(A); 146 if (l1.pointonseg(B))f = 1; 147 else if (l2.pointonseg(t))f = 1; //求B的对称点会WA 148 else f = 0; 149 } 150 if (f == 1) 151 printf("Case #%d: Yes\n", d++); 152 else 153 printf("Case #%d: No\n", d++); 154 } 155 return 0; 156 }
(。・∀・)ノ
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架