Description
给出一个圆的圆心(x,y)和半径r,从原点向该圆上一点连一条线段(线段与圆只能有一个交点),问连向哪一个点可以使得这条线段的长度最长
Input
第一行一整数T表示用例组数,每组用例输入三个整数x,y,r分别表示圆心的横纵坐标和半径(1<=T<=1e5,1<=r<=x,y<=1000)
Output
对于每组用例,输出满足条件的点的横纵坐标,如果有多种方案则输出其中横坐标较小的点,结果保留六位小数
Sample Input
3
1 1 1
2 2 1
4 5 2
Sample Output
0.000000 1.000000
1.088562 2.411438
2.126155 5.699076
Solution
问题转化为从原点向该圆做切线,求横坐标较小的一个切点B(a,b),如下图
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 1111
int main()
{
int T;
double x,y,r;
scanf("%d",&T);
while(T--)
{
scanf("%lf%lf%lf",&x,&y,&r);
double t=x*x+y*y-r*r;
double b=(t*y+x*r*sqrt(t))/(x*x+y*y);
double a=(t*x-y*r*sqrt(t))/(x*x+y*y);
printf("%.6lf %.6lf\n",a,b);
}
return 0;
}