問題の意味:楕円所与\(AX ^ 2 + ^によって 2 + CZ ^ 2 + dyz + EXZ + FXY = 1 \) \(A、B、C、D、E、F \) 、楕円探しする球点((0,0,0)\)\は最短距離です。
直接2次元の私は本当に時間以上の操作を行い、この質問の三次元プロモーションへの距離の式、偶数サンプルは行くだろうまで、A ??? Iの結果のうち、支払いは、これを行うに多くの時間を無駄に?タイトルの数式を使用すると、直接デバッグを継続テンプレートの様々なパラメータを設定することができ、あなたに言ってきました。
OH、又は球面上の点を決定する方法について話を\((X、Y、Z)\) 、ランダム来る\(X、Yの\)の後に、\(Zが\)上記式に従って算出します。上記式は、で修飾されている\(CZ ^ 2 +(Dyを+ EX)+ AX ^ Z ^ 2 + 0 = 2により1 FXY + \) 、線形方程式式缶を解決するための直接法を用いて。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
double a,b,c,d,e,f,ansx,ansy,ansz;
const double inf=1e18;
inline double dist(double x,double y,double z){
return sqrt(x*x+y*y+z*z);
}
inline double calc(double x,double y){
double A=c,B=e*x+d*y,C=a*x*x+b*y*y+f*x*y-1.0;
double delta=B*B-4.0*A*C;//公式啊
if(delta<0)return inf;//初中知识啊
double z1=(-B+sqrt(delta))/(2.0*A),z2=(-B-sqrt(delta))/(2.0*A);
if(dist(x,y,z1)<dist(x,y,z2))return z1;//两个解选最优的
return z2;
}
inline void mnth(){
double T=2333,eps=1e-15;
while(T>eps){
double nowx=ansx+(rand()*2-RAND_MAX)*T;
double nowy=ansy+(rand()*2-RAND_MAX)*T;
double nowz=calc(nowx,nowy);
if(nowz==inf){T*=0.997;continue;}
double delta=dist(nowx,nowy,nowz)-dist(ansx,ansy,ansz);
if(delta<0)ansx=nowx,ansy=nowy,ansz=nowz;
else if(exp(delta/T)*RAND_MAX<rand())ansx=nowx,ansy=nowy,ansz=nowz;
T*=0.997;
}
}
int main(){
//srand((int)time(NULL));//HDU应该是不支持这个
srand(19260817);//随便搞个数就行
while(scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f)!=EOF){
ansx=0;ansy=0;ansz=sqrt(1.0/c);
mnth();printf("%.10lf\n",dist(ansx,ansy,ansz));
}
return 0;
}