Ellipsoid

HDU

The meaning of problems: Given an ellipsoid \ (ax ^ 2 + by ^ 2 + cz ^ 2 + dyz + exz + fxy = 1 \) a \ (A, B, C, D, E, F \) , seeking ellipsoidal sphere point to \ ((0,0,0) \) is the shortest distance.

Distance formula directly from two-dimensional to three-dimensional promotion of this question I really do more than an hour, until even the sample would go, pay out of the results of the A ??? I wasted so much time doing it this ??? title formulas have told you, you can directly set various parameters of the template continue debugging.

Oh, or talk about how to determine a point on the spherical surface \ ((X, Y, Z) \) , random come \ (x, y \) after, \ (Z \) to be calculated according to the above formula. the above formula is modified at \ (CZ ^ 2 + (Dy + EX) + AX ^ Z ^ 2 + by 2 = 0. 1-FXY + \) , using the direct method to solve linear equations formula can.

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

Guess you like

Origin www.cnblogs.com/PPXppx/p/11668603.html
Recommended