题解:使用模拟退火算法,先设ansx=0,ansy=0,ansz=sqrt(1.0/c),然后进行模拟退火算法,最后得出答案
附上代码:
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-10;
double a,b,c,d,e,f;
double ansx,ansy,ansz;
double dis(double x,double y,double z)
{
return sqrt(x*x+y*y+z*z);
}
double calc(double x,double y)
{
double A=c;
double B=d*y+e*x;
double C=a*x*x+b*y*y+f*x*y-1.0;
double delta=B*B-4.0*A*C;
if(delta<0)return 210000000.0;
double x1=(-B+sqrt(delta))/(2.0*A);
double x2=(-B-sqrt(delta))/(2.0*A);
if(dis(x,y,x1)>dis(x,y,x2))return x2;
return x1;
}
void MNTH()
{
double T=10000;
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==210000000.0){QT*=0.99;continue;}
double delta=dis(nowx,nowy,nowz)-dis(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.99;
}
printf("%.6lf\n",dis(ansx,ansy,ansz));
}
int main()
{
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();
}
return 0;
}