列表

详情


NC252844. Meteor Shower

描述

Colin heard that there will be a meteor shower in a few days. As a romantic boyfriend, he plans to take Eva to admire it.

To simplify the problem, we will consider it on a two-dimensional plane.

Assuming the Earth is a circle with origin O as its center and r as its radius. The points on the circle form the surface of the Earth (i.e. points satisfy x^2+y^2=r^2). A meteor shower contains n meteors. Each meteor is given by a point (x_i, y_i) on the two-dimensional plane representing the point at which a meteor appears at a certain moment, and a direction vector (dx_i, dy_i) representing the direction of its movement, the meteor will move continuously in this direction unless it collides with the Earth, that means we don't consider the collision between meteors (i.e. the movements of different meteors are independent).



In order to give Eva the best experience, Colin decided to take her to the optimal observation site, which is said to be the closest point on the surface of Earth to the trace of the given meteor. Watching a meteor is not always safe. Once a meteor collides with Earth, it is called a meteorite. If it will be a meteorite, Colin will take Eva to witness the place it crash. So Colin wants to know whether or not a meteor will collide with Earth (if it comes into contact with the Earth's surface, it is considered a collision). If it will, Colin wants to know the point it crash; and if not, Colin wants to know where the optimal observation site is.

Please determine whether a meteor will collide with the Earth:
  • If it does, output "Crash at (x,y)", (x,y) is the point the meteorite crashed.
  • If it does not, output "Observe at (x,y)", (x,y) is the optimal observation point.
All the coordinates you output should be rounded into 4 decimals.

输入描述

The first line contains two positive integers n,r \text{ }(1 \le n \le 10^5, 1 \le r \le 10^9 ) , representing the number of meteors and the radius of the earth.

For the following n lines, each line contains four integers x_i,y_i,dx_i, dy_i \text{ } (-10^9 \le x_i,y_i,dx_i,dy_i \le 10^9, (dx_i, dy_i) \neq (0,0)) ; (x_i,y_i) represents the start point of the i-th meteor and (dx_i,dy_i) represents the moving direction of the i-th meteor.

It's guaranteed that the distance between origin O and the start point of a meteor is at least r+0.1 .

输出描述

Output n lines, each line represents the answer of the i-th meteor:

If the i-th meteor collide with the Earth, output "Crash at (x,y)"; (x,y) is the point the meteorite crashed. If it does not, output "Observe at (x,y)"; (x,y) is the optimal observation point. (without quotes)

All the coordinates you output should be rounded into 4 decimals, and the coordinates you output will be considered correct if the absolute error to the jury does not exceed 10^{-3} .

示例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;
}



上一题