描述
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
5 3 3 1 1
output
3.7677669529663684 3.7677669529663684 3.914213562373095
input
10 5 5 5 15
output
5.0 5.0 10.0
思路
先说题意,给你一个圆和一个点,让你在给定圆内画一个圆,使得答案圆不能包含给定点,而且使得给定圆没有被答案圆覆盖的面积最小。输出答案圆的圆心和半径即可。
分三种情况考虑:
- 当点在圆外时:
那么给出的圆就符合条件,直接输出圆心和坐标即可 - 当给出的点和圆心重合时:
此时的坐标为(x1+r/2,y1),半径为r/2 - 当给出的点在圆内时:
如图,以样例1进行说明:
圆心为点A,给出的点为C,那么要使做一个圆内最大的圆,就过线段CA做射线,交圆为一点D,则以CD为直径的圆就是所求的圆。半径很好得出,在求圆心的点的坐标使,需要用到三角形的相似,如图:
已知 C C 点坐标,D点的坐标为 (x1,y1) ( x 1 , y 1 ) ,我们现在要求出A点的坐标,那么只需要求出 CB C B 和 BA B A ,由三角形的相似可以得出:
ACCD=CBCE A C C D = C B C E
则:
BC=CE∗ACCD B C = C E ∗ A C C D
这样就可以求出来,圆心的坐标
代码
#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const int N=1000+2;
double dis(double x1,double y1,double x2,double y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int main()
{
double r,x1,x2,y1,y2;
scanf("%lf%lf%lf%lf%lf",&r,&x1,&y1,&x2,&y2);
double len=dis(x1,y1,x2,y2);
if(len>=r*r)
printf("%lf %lf %lf\n",x1,y1,r);
else if(x1==x2&&y1==y2)
printf("%lf %lf %lf\n",x1+r/2,y1,r/2);
else
{
double Z=sqrt(len);
double R=(Z+r)/2;
printf("%lf %lf %lf",(x1-x2)*R/Z+x2,(y1-y2)*R/Z+y2,R);
}
return 0;
}