hdu 5017 ellipsoid 退火大法

来源:互联网 发布:js 数组转对象 编辑:程序博客网 时间:2024/05/22 04:53

题目链接:点击打开链接

题意:给形如ax^2+by^2+cz^2+dxy+eyz+fxz=1的椭球面方程,求椭球面距离原点最近的距离。

思路:可知由不是最优到最优之间有一条路径是递减的,退火大法好!!

cpp:

#include <cstdio>#include <algorithm>#include <cmath>using namespace std;#define INF 1e10const double eps=1e-4;int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,-1,1,-1,1};double a,b,c,d,e,f;double get_dis(double x, double y, double z) {return sqrt(x*x+y*y+z*z);}double get_z(double x,double y) {double A,B,C; A=c,B=e*x+d*y,C=a*x*x+b*y*y+f*x*y-1;double temp=B*B-4*A*C;if (temp<0) return INF;double ret1,ret2; ret1=(-B+sqrt(temp))/2/A;ret2=(-B-sqrt(temp))/2/A;if (fabs(ret1)<fabs(ret2)) return ret1;else return ret2;}void simulated_annealing() {double step,ret,x,y,z;step = 1;ret=INF;x=0,y=0,z=get_z(x,y);while (step>eps) {for (int i=0;i<8;i++) {double nx,ny,nz;nx=x+dx[i]*step;ny=y+dy[i]*step;nz=get_z(nx,ny);if (nz>=INF) continue;double tp=get_dis(nx,ny,nz);if (tp<ret) {x=nx;y=ny;z=nz;ret=tp;}}step*=0.97;}printf("%.8f\n",ret);}int main() {while (~scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f))simulated_annealing();    return 0;}


0 0