题意:
有个圆,圆内有两个点P,Q,已知PO=QO,求圆上一点D,使得PD+QD最小
思路:
1002 Mindis
很不幸不总是中垂线上的点取到最小值,考虑点在圆上的极端情况。
做P点关于圆的反演点P',OPD与ODP'相似,相似比是|OP| : r。
Q点同理。
极小化PD+QD可以转化为极小化P'D+Q'D。
当P'Q'与圆有交点时,答案为两点距离,否则最优值在中垂线上取到。
时间复杂度 O(1)
也有代数做法,结论相同。
优秀的黄金分割三分应该也是可以卡过的。
人家的题解说的很好,可是比赛的时候就一门心思改着三分,多年没碰几何,还是多积累积累经验吧,
这题也没什么特别要说的
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
int x1,y1,y2,x2,r;
double xx1,yy1,xx2,yy2,dis,ans;
double a,b,c;
while(t--)
{
scanf("%d%d%d%d%d",&r,&x1,&y1,&x2,&y2);
a=sqrt(x1*x1+y1*y1);
if(x1==x2&&y1==y2)
{
printf("%.7f\n",2.0*(r-a));
continue;
}
c=(1.0*a)/(1.0*r);
a=1.0*r*r/(a*a);
xx1=x1*a;
yy1=y1*a;
xx2=x2*a;
yy2=y2*a;
dis=fabs((yy2-yy1)*(-xx1)-(xx2-xx1)*(-yy1))/( sqrt((xx1-xx2)*(xx1-xx2)+(yy2-yy1)*(yy2-yy1)));
ans= sqrt((xx1-xx2)*(xx1-xx2)+(yy2-yy1)*(yy2-yy1));
if(dis>r) {
dis-=r;
ans=2*sqrt((ans/2.0)*(ans/2.0) + dis*dis);
}
printf("%.7f\n",ans*c);
}
return 0;
}
等三分卡过了,再来补个代码。。。。