1. 程式人生 > >5017 Ellipsoid 模擬退火

5017 Ellipsoid 模擬退火

Given a 3-dimension ellipsoid(橢球面) 

your task is to find the minimal distance between the original point (0,0,0) and points on the ellipsoid. The distance between two points (x 1,y 1,z 1) and (x 2,y 2,z2) is defined as 

Input

There are multiple test cases. Please process till EOF.  For each testcase, one line contains 6 real number a,b,c(0 < a,b,c,< 1),d,e,f (0 ≤ d,e,f < 1)

, as described above. It is guaranteed that the input data forms a ellipsoid. All numbers are fit in double. 

Output

For each test contains one line. Describes the minimal distance. Answer will be considered as correct if their absolute error is less than 10 -5.

Sample Input

1 0.04 0.01 0 0 0

Sample Output

1.0000000

題解:解決最優解的問題,模擬退火

注意括號啊,坑死

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define eps 1e-8
double a,b,c,d,e,f;
#define INF 1e15
int fx[5]={0,0,1,-1};
int fy[5]={1,-1,0,0};
double judge_(double x,double y)
{
	double A,B,C;
	A=c;
	B=d*y+e*x;
	C=a*x*x+b*y*y+f*x*y-1;
	if(B*B-4*A*C<0) return INF;
	double x1=(-B-sqrt(B*B-4*A*C))/2/A;
	double x2=(-B+sqrt(B*B-4*A*C))/2/A;
	return sqrt(x*x+y*y+min(x2*x2,x1*x1));
}
int main()
{
	while(scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f)!=EOF)
	{
		double ans,x=sqrt(1.0/a),y=0,t=1.0,xx,yy;
		while(t>eps)
		{
			ans=judge_(x,y);
			int i;
			for(i=0;i<4;i++)
			{
				xx=x+t*fx[i];
				yy=y+t*fy[i];
				if(judge_(xx,yy)+eps<ans)
					break;
			}
			if(i!=4)
				x=xx,y=yy;
			else
				t*=0.518;
		}
		ans=judge_(x,y);
		printf("%.7f\n",ans);
	}
	return 0;
}