Codeforces Round #465 (Div. 2) C. Fifa and Fafa

C. Fifa and Fafa

Fifa and Fafa are sharing a flat. Fifa loves video games and wants to download a new soccer game. Unfortunately, Fafa heavily uses the internet which consumes the quota. Fifa can access the internet through his Wi-Fi access point. This access point can be accessed within a range of r meters (this range can be chosen by Fifa) from its position. Fifa must put the access point inside the flat which has a circular shape of radius R. Fifa wants to minimize the area that is not covered by the access point inside the flat without letting Fafa or anyone outside the flat to get access to the internet.

The world is represented as an infinite 2D plane. The flat is centered at (x1, y1) and has radius R and Fafa's laptop is located at (x2, y2), not necessarily inside the flat. Find the position and the radius chosen by Fifa for his access point which minimizes the uncovered area.

Input

The single line of the input contains 5 space-separated integers R, x1, y1, x2, y2 (1 ≤ R ≤ 105|x1|, |y1|, |x2|, |y2| ≤ 105).

Output

Print three space-separated numbers xap, yap, r where (xap, yap) is the position which Fifa chose for the access point and r is the radius of its range.

Your answer will be considered correct if the radius does not differ from optimal more than 10 - 6 absolutely or relatively, and also the radius you printed can be changed by no more than 10 - 6 (absolutely or relatively) in such a way that all points outside the flat and Fafa's laptop position are outside circle of the access point range.

Examples
input
Copy
5 3 3 1 1
output
3.7677669529663684 3.7677669529663684 3.914213562373095
input
Copy
10 5 5 5 15
output
5.0 5.0 10.0

题意:给你一个圆形房子,因为有圆心和半径。接着给你一个电脑位置x2,y2,这个位置是不能覆盖的禁止点。现在你有一个wifi,以你为中心,可以辐射半径任意大,这wifi挺厉害的,现在问你在不覆盖禁止点前提下,将房子覆盖到最大,输出这个wifi覆盖最大的圆心和半径。

思路:首先思路还是很好想的,既然要圆面积最大,那么新圆直径肯定要确定的足够大,所以以禁止点为起点,连接房子圆心后直接延长至房子边缘,这个长度就是新圆的直径,该直径对应的圆就是最大圆。

那么直径的长度就是:禁止点到房子圆心+房子半径=d+R,半径就有了,关键是找圆心。

Codeforces Round #465 (Div. 2) C. Fifa and Fafa_第1张图片

由上图,读了题应该不难理解,A禁止点,O房子圆心,O1所求圆心,B所求的点,B点必然位于房子圆上。如果已知圆上两点,且两点连线过圆心,那么可得圆心:AB两点横纵坐标相加除以2。

关于B点坐标,△AOP与△ABP1相似,AO OP AP均已知,那么相似求得的AP1 BP1就是B点坐标,圆心即可得到。最后注意特判A和O重合的情况,此时新圆半径R/2。

#include
#define ll long long
using namespace std;
int main()
{
    double R,x1,x2,y1,y2;
    while(~scanf("%lf%lf%lf%lf%lf",&R,&x1,&y1,&x2,&y2))
    {
        double d=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
        if(d>=R)printf("%.9f %.9f %.9f" ,x1,y1,R);  //在外边直接输出房子就好
        else if(d == 0)printf("%.9f %.9f %.9f",x1,y1-(R/2),(R/2)); //重合时特判
        else
        {
            double r = (d + R)/2;
            double x = x2 + r*((x1-x2)/d);
            double y = y2 + r*((y1-y2)/d);
            printf("%.9f %.9f %.9f",x,y,r);
        }
    }
    return 0;
}

你可能感兴趣的:(Codeforces)