题干:
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,z 2) 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
题目大意:
求椭圆上离圆心最近的点的距离。
解题报告:
先解方程,然后模拟退火。但是发现这个题无论如何也调不出样例,无奈改爬山算法。(正解是三分)
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const double eps = 1e-10;
const double GG = 12398734577LL;
const int MAX = 2e5 + 5;
int nx[8] = {1,1,1,0,0,-1,-1,-1};
int ny[8] = {1,0,-1,1,-1,1,0,-1};
double a,b,c,d,e,f;
//double Rand(){return rand()%(RAD+1)/(1.0*RAD);}//随机产生0-1的浮点数
double calz(double x,double y) {double A=c,B=(d*y+e*x),C=f*x*y+a*x*x+b*y*y-1;double det = B*B-4*A*C;if(det < 0) return GG;double z1 = (-B+sqrt(det))/(2*A);double z2 = (-B-sqrt(det))/(2*A);if(fabs(z1)<fabs(z2)) return z1;else return z2;
// return min(z1,z2);
}
double solve(double curx,double cury) {curx=0,cury=0;double T = 1,ansdis = GG;while(T>eps) {for(int i = 0; i<8; i++) {double tx = curx + nx[i]*T;double ty = cury + ny[i]*T;double tz = calz(tx,ty);if(fabs(tz-GG) < eps) continue;double tmpdis = sqrt(tx*tx+ty*ty+tz*tz);if(tmpdis < ansdis) {ansdis = tmpdis;curx = tx;cury = ty;}}T*=0.99;}return ansdis;
}
int main()
{while(~scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f)) {double ans = 12312312313LL;ans = min(ans,solve(1/sqrt(a),0));ans = min(ans,solve(0,1/sqrt(b)));printf("%.6f\n",ans);}return 0 ;
}