题目链接:传送门
Mindis
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1479 Accepted Submission(s): 210
Special Judge
Problem Description
The center coordinate of the circle C is O, the coordinate of O is (0,0) , and the radius is r.
P and Q are two points not outside the circle, and PO = QO.
You need to find a point D on the circle, which makes PD+QD minimum.
Output minimum distance sum.
P and Q are two points not outside the circle, and PO = QO.
You need to find a point D on the circle, which makes PD+QD minimum.
Output minimum distance sum.
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each case begins with one line with r : the radius of the circle C.
Next two line each line contains two integers x , y denotes the coordinate of P and Q.
Limits
T≤500000
−100≤x,y≤100
1≤r≤100
Each case begins with one line with r : the radius of the circle C.
Next two line each line contains two integers x , y denotes the coordinate of P and Q.
Limits
T≤500000
−100≤x,y≤100
1≤r≤100
Output
For each case output one line denotes the answer.
The answer will be checked correct if its absolute or relative error doesn't exceed 10−6 .
Formally, let your answer be a, and the jury's answer be b. Your answer is considered correct if |a−b|max(1,b)≤10−6 .
The answer will be checked correct if its absolute or relative error doesn't exceed 10−6 .
Formally, let your answer be a, and the jury's answer be b. Your answer is considered correct if |a−b|max(1,b)≤10−6 .
Sample Input
4 4 4 0 0 4 4 0 3 3 0 4 0 2 2 0 4 0 1 1 0
Sample Output
5.6568543 5.6568543 5.8945030 6.7359174
题目大意:给出原点O,及P,Q点坐标,且|PO| = |QO|,又给出一个以O为圆心,半径为R的圆C,在圆上任取一点D,使|DO|+|PO|最小。
官方题解:
找出点P关于圆C的反演点P'
那么有三角形DPO与三角形DP'O相似,相似比为|PO|:R
Q点同理
极小化|PD|+|QD|可以转换为|P'D|+|Q'D|
当P'D'与圆有交点时,答案为两点距离,否则最优点在中垂线上取到
小丢丢补充:
令|PO| = m,|P'O| = n,有m*n = R*R
|PO|:|DO| = m:R = sqrt(m:n),|DO|:|P'O| = R:n = sqrt(m:n)
所以三角形DPO与三角形DP'O相似
又|DO|:|P'O| = |DO|:|Q'O|,有|P'O| = |Q'O|,所以P'Q'O是等腰三角形,中垂线过O点
当P'Q'与圆C相离,以P',Q'为焦点做椭圆与C相切,切点为P'Q'上垂直平分线与C的交点,即明显此时|DP'|+|DQ'|最小
最后一句——每次都是被大佬们碾压得渣都不剩呀
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const double eps = 1e-8;
int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x > 0 ) return 1;
else return -1;
}
double judge()
{
double R,x1,y1,x2,y2;
scanf("%lf%lf%lf%lf%lf",&R,&x1,&y1,&x2,&y2);
double r = sqrt(x1*x1+y1*y1);
if(sgn(r) == 0) return 2*R;
double k = (R*R)/(r*r);
double x3,y3,x4,y4,mx,my,dis,ans;
x3 = k*x1; y3 = k*y1; //反演点p'
x4 = k*x2; y4 = k*y2; //反演点q'
mx = (x3+x4)/2;
my = (y3+y4)/2;
dis = sqrt(mx*mx+my*my);
if(sgn(dis-R)<=0){
ans = sqrt((x4-x3)*(x4-x3)+(y4-y3)*(y4-y3));
}else{
ans = 2*sqrt((dis-R)*(dis-R)+(mx-x3)*(mx-x3)+(my-y3)*(my-y3));
}
return ans*r/R;
}
int main()
{
int T;
scanf("%d",&T);
while( T-- ){
printf("%.7lf\n",judge());
}
return 0;
}