NC252844. Meteor Shower
描述
输入描述
The first line contains two positive integers, representing the number of meteors and the radius of the earth.
For the followinglines, each line contains four integers
;
represents the start point of the
-th meteor and
represents the moving direction of the
-th meteor.
It's guaranteed that the distance between originand the start point of a meteor is at least
.
输出描述
Outputlines, each line represents the answer of the
-th meteor:
If the-th meteor collide with the Earth, output "Crash at
";
is the point the meteorite crashed. If it does not, output "Observe at
";
is the optimal observation point. (without quotes)
All the coordinates you output should be rounded intodecimals, and the coordinates you output will be considered correct if the absolute error to the jury does not exceed
.
示例1
输入:
5 1 1 1 -1 0 2 2 -1 -1 2 1 -1 -1 2 3 -1 0 -1 -1 -1 -1
输出:
Crash at (0.0000,1.0000) Crash at (0.7071,0.7071) Crash at (1.0000,0.0000) Observe at (0.0000,1.0000) Observe at (-0.7071,-0.7071)
说明:
The result of the example is shown as the image in the discription.C++(g++ 7.5.0) 解法, 执行用时: 380ms, 内存消耗: 4536K, 提交时间: 2023-07-15 17:18:13
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 7; const double eps = 1e-8; double r; void solve() { double sx, sy, dx, dy; cin >> sx >> sy >> dx >> dy; double a = (dx * dx + dy * dy), b = (2 * sx * dx + 2 * sy * dy), c = (sx * sx + sy * sy - r * r); auto delta = b * b - 4ll * a * c; if (delta >= 0) { auto t1 = (-b + sqrt(delta)) / (2.0 * a), t2 = (-b - sqrt(delta)) / (2.0 * a); if (t2 < -eps) { dx = (sx); dy = (sy); auto tt = sqrt(1.0 * (r * r) / (dx * dx + dy * dy)); printf("Observe at (%.4lf,%.4lf)\n", tt * dx, tt * dy); } else printf("Crash at (%.4lf,%.4lf)\n", sx + t2 * dx, sy + t2 * dy); } else { auto t = -(sx * dx + sy * dy) / a; dx = (sx + max(t, 0.0) * dx); dy = (sy + max(t, 0.0) * dy); auto tt = sqrt(1.0 * (r * r) / (dx * dx + dy * dy)); printf("Observe at (%.4lf,%.4lf)\n", tt * dx, tt * dy); } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(4); int T; cin >> T >> r; while (T--) solve(); return 0; }
C++(clang++ 11.0.1) 解法, 执行用时: 738ms, 内存消耗: 4536K, 提交时间: 2023-07-01 22:04:09
#include <bits/stdc++.h> #define pow2(a) ((a)*(a)) using namespace std; typedef long long ll; int n; double r,x,y,dx,dy; double ansx,ansy,a,h,l,b,c,h2; int main() { cin>>n>>r; while(n--) { cin>>x>>y>>dx>>dy; a=1.0*abs(x*dx+y*dy)/sqrt(pow2(dx)+pow2(dy)); h2=pow2(x)+pow2(y)-1.0*pow2(x*dx+y*dy)/(pow2(dx)+pow2(dy)); h=sqrt(h2); c=sqrt(pow2(x)+pow2(y)); if((pow2(dx)+pow2(dy))*(pow2(x)+pow2(y))-pow2(x*dx+y*dy)<=pow2(r)*(pow2(dx)+pow2(dy))) { if(-x*dx-y*dy<0) { ansx=1.0*x*r/c; ansy=1.0*y*r/c; printf("Observe at (%.4f,%.4f)\n",ansx,ansy); } else { b=sqrt(pow2(r)-pow2(h)); l=a-b; ansx=x+1.0*l/sqrt(pow2(dx)+pow2(dy))*dx; ansy=y+1.0*l/sqrt(pow2(dx)+pow2(dy))*dy; printf("Crash at (%.4f,%.4f)\n",ansx,ansy); } } else { if(-x*dx-y*dy<0) { ansx=1.0*x/c*r; ansy=1.0*y/c*r; } else { ansx=(x+1.0*a/sqrt(pow2(dx)+pow2(dy))*dx)*r/h; ansy=(y+1.0*a/sqrt(pow2(dx)+pow2(dy))*dy)*r/h; } printf("Observe at (%.4f,%.4f)\n",ansx,ansy); } } return 0; }