多校 HDU6097 Mindis (几何)

题意:

有个圆,圆内有两个点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)O(1)

也有代数做法,结论相同。

优秀的黄金分割三分应该也是可以卡过的。

多校 HDU6097 Mindis (几何)_第1张图片

多校 HDU6097 Mindis (几何)_第2张图片

人家的题解说的很好,可是比赛的时候就一门心思改着三分,多年没碰几何,还是多积累积累经验吧,

这题也没什么特别要说的

#include
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;
}

等三分卡过了,再来补个代码。。。。






你可能感兴趣的:(多校,数学,几何,积分)