标签:des style http color io os ar for strong


1 0.04 0.01 0 0 0
1.0000000
题目大意:
求一个椭球面上的一个点到原点的最短距离。
解题思路:
模拟退火,不多解释了。
解题代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double eps=1e-8;
const double INF=1e100;
const int offx[]={1,0,-1,0,1,-1,-1,1};
const int offy[]={0,1,0,-1,1,1,-1,-1};
double a,b,c,d,e,f;
double getAns(double x,double y){
double A=c,B=d*y+e*x,C=a*x*x+b*y*y+f*x*y-1.0;
double delta=B*B-4*A*C;
if(delta<0) return INF+10;
delta=sqrt(delta);
double z1=(-B+delta)/(2*A),z2=(-B-delta)/(2*A);
return min( sqrt(x*x+y*y+z1*z1) , sqrt(x*x+y*y+z2*z2) );
}
double tosolve(double sx,double sy){
double x=sx,y=sy,ans=getAns(sx,sy),step=1e6;
while(step>eps){
double sx=x,sy=y;
bool flag=false;
for(int i=0;i<8;i++){
double dx=x+offx[i]*step,dy=y+offy[i]*step;
double tmp=getAns(dx,dy);
if(tmp>=INF) continue;
if(tmp<ans){
ans=tmp;
flag=true;
sx=dx,sy=dy;
}
}
x=sx,y=sy;
if(!flag) step/=2;
}
return ans;
}
void solve(){
//cout<<tosolve(0,0)<<" "<<tosolve(sqrt(1.0/a),0)<<" "<<tosolve(0,sqrt(1.0/b))<<endl;
double ans=tosolve(0,0),tmp;
tmp=tosolve(sqrt(1.0/a),0);
if(tmp<ans) ans=tmp;
tmp=tosolve(-sqrt(1.0/a),0);
if(tmp<ans) ans=tmp;
tmp=tosolve(0,sqrt(1.0/b));
if(tmp<ans) ans=tmp;
tmp=tosolve(0,-sqrt(1.0/b));
if(tmp<ans) ans=tmp;
printf("%.7lf\n",ans);
}
int main(){
while(scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f)!=EOF){
solve();
}
return 0;
}
HDU 5017 Ellipsoid (计算几何,模拟退火)
标签:des style http color io os ar for strong
原文地址:http://blog.csdn.net/a1061747415/article/details/39830299