CSU 1503 點到圓弧的距離 (拉格朗日乘數法)

題目鏈接:CSU 1503 點到圓弧的距離

中文題。

思路:求一個二元函數在圓弧上的極值,加上端點的值,一起取個最小就是答案。



注意:1+λ爲0時,P點在圓心,最短距離自然是半徑。

求的極值點在圓的優弧或是劣弧的判斷可以將直角座標系轉爲極座標,用角度判斷。

還有就是最坑的精度,精度要達到0.0001


AC代碼;


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const double eps=0.0001;
const double PI=acos(-1.0);
struct Point
{
	double x,y;
};

Point waixion(Point a,Point b,Point c)
{
	Point e;
	double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1)/2;
	double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2)/2;
	double d = a1*b2 - a2*b1;
	e.x=a.x + (c1*b2 - c2*b1)/d;
	e.y=a.y + (a1*c2 -a2*c1)/d;
	return e;
}

double dis(Point a,Point b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double cross(Point a,Point b)
{
	return b.x*a.y-a.x*b.y;
}

double angle(Point a,Point c,double r)
{
	double aa,d;
	d=dis(a,c);
	aa=acos((a.x-c.x)/d);
	if((sin(aa)*d-(a.y-c.y))<=eps)
		return aa;
	return 2*PI-aa;

}

int main()
{
	double h;
	int cas = 0;
	double ans1,r,x,y;
	Point yx,a,b,c,p,ans;
	while(scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y)!=EOF)
	{
		scanf("%lf%lf",&p.x,&p.y);
		yx=waixion(a,b,c);
		r=dis(yx,a);
		h=sqrt(((p.x-yx.x)*(p.x-yx.x)+(p.y-yx.y)*(p.y-yx.y))/(r*r))-1;

		if(fabs(p.x-yx.x)<=eps && fabs(p.y-yx.y)<=eps)
		{
			printf("Case %d: %.3lf\n",++cas,r);
			continue;
		}
		ans.x=(h*yx.x+p.x)/(1+h);
		ans.y=(h*yx.y+p.y)/(1+h);

		double ja,jb,jc,jp;

		ja=angle(a,yx,r);
		jb=angle(b,yx,r);
		jc=angle(c,yx,r);
		jp=angle(p,yx,r);

		//printf("a:%lf\nb:%lf\nc:%lf\np:%lf\n",ja,jb,jc,jp);
		if(ja>jc)
			swap(ja,jc);
		if(ja-jb<=eps && jb-jc<=eps)//ja<jb<jc
		{
			if(ja-jp<=eps && jp-jc<=eps)
				ans1= dis(ans,p);
			else
				ans1=9999999999.0;
		}
		else 
		{
			if(ja-jp<=eps && jp-jc<=eps)
				ans1=9999999999.0;
			else
				ans1= dis(ans,p);
		}
		double ans2 = dis(a,p);
		double ans3 = dis(c,p);
		double ans = min(ans1,ans2);
		ans = min(ans,ans3);
		//printf("%.2lf %.2lf %.2lf....\n",ans1,ans2,ans3);
		printf("Case %d: %.3lf\n",++cas,ans);
	}
	return 0;
}
/*
0 0 1 -1 2 0 1 -1
0 0 1 1 2 0 0 1
3 4 0 -5 -3 4 0 1
3 4 0 5 -3 4 0 1
1 0 -1 0 0 -1 1 -1
*/





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章