一般上大家都会想到与所选点对立的那个顶点就是最远,这明显是错误的,举个例子:a=100,b=1,c=1;答案应该是100.50626871
首先长方体每个顶点等价,枚举任意一个点就好。
其次一个点最远的距离显然是在3个与其不相邻的面取到的。
所以这时候需要枚举其这三个面上所有的点进行比较。由于面上点没有单调性,所以不能二分,要三分。。。
具体怎么做呢?首先枚举三个面,每个面先枚举长,在枚举宽,然后算一下长度,在进行比较,轻松出解
#include<bits/stdc++.h>
using namespace std;
double l,w,h;
double f(double a,double b,double c){return (a+b)*(a+b)+c*c;}
double ff(double a){return a*a;}
double solve(double a,double b,double c)//比较点到该面上的长度
{
double ans=1e20;
if(a!=l)ans=min(ans,f(c,b,a));
else if(a==l)ans=min(ans,min(ff(w+c)+ff(l+w-b),ff(h+b)+ff(l+h-c)));
if(b!=w) ans=min(ans,f(a,c,b));
else if(b==w)ans=min(ans,min(ff(l+c)+ff(l+w-a),ff(h+a)+ff(w+h-c)));
if(c!=h) ans=min(ans,f(a,b,c));
else if(c==h)ans=min(ans,min(ff(w+a)+ff(h+w-b),ff(l+b)+ff(l+h-a)));
return ans;
}
double solvexy(double a,double b,double c)
{
double l=0,r=c,ans=0;int t=100;
while(t--)
{
double m1=(l*2+r)/3;
double m2=(l+2*r)/3;
double tmp1=solve(a,b,m1);
double tmp2=solve(a,b,m2);
ans=max(ans,max(tmp1,tmp2));
if(tmp1>tmp2)r=m2;else l=m1;
}return ans;
}
double solvexz(double a,double b,double c)
{
double l=0,r=b,ans=0;int t=100;
while(t--)
{
double m1=(l*2+r)/3;
double m2=(l+2*r)/3;
double tmp1=solve(a,m1,c);
double tmp2=solve(a,m2,c);
ans=max(ans,max(tmp1,tmp2));
if(tmp1>tmp2)r=m2;else l=m1;
}return ans;
}
double solvex(double a,double b,double c)//枚举yz面
{
double l=0,r=b,ans=0;int t=100;
while(t--)
{
double m1=(l*2+r)/3;
double m2=(l+2*r)/3;
double tmp1=solvexy(a,m1,c);
double tmp2=solvexy(a,m2,c);
ans=max(ans,max(tmp1,tmp2));
if(tmp1>tmp2)r=m2;else l=m1;
}return ans;
}
double solvey(double a,double b,double c)//枚举xz面
{
double l=0,r=a,ans=0;int t=100;
while(t--)
{
double m1=(l*2+r)/3;
double m2=(l+r*2)/3;
double tmp1=solvexy(m1,b,c);
double tmp2=solvexy(m2,b,c);
ans=max(ans,max(tmp1,tmp2));
if(tmp1>tmp2)r=m2;else l=m1;
}return ans;
}
double solvez(double a,double b,double c)//枚举xy面
{
double l=0,r=a,ans=0;int t=100;
while(t--)
{
double m1=(l*2+r)/3;
double m2=(l+r*2)/3;
double tmp1=solvexz(m1,b,c);
double tmp2=solvexz(m2,b,c);
ans=max(ans,max(tmp1,tmp2));
if(tmp1>tmp2)r=m2;else l=m1;
}return ans;
}
int main()
{
double ans;scanf("%lf%lf%lf",&l,&w,&h);
ans=min(f(l,w,h),min(f(l,h,w),f(h,w,l)));
ans=max(ans,solvex(l,w,h));
ans=max(ans,solvey(l,w,h));
ans=max(ans,solvez(l,w,h));
printf("%.8lf\n",sqrt(ans));return 0;
}