题面
https://vjudge.net/problem/Gym-101981A
题意
给n个在三维坐标上的点(x,y,z),在空间中假设有一个点a,求每个点到点a的距离的最大值,而题目要使得这个最大值最小
思路
分析可得,对于每一维,另外两维固定后,另一维和答案的关系呈一个凹函数,所以可以使用三分套三分套三分的方法,使用递归来实现
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const double pi=acos(-1);
const double feps=1e-8;
const int maxn=6000;
struct point
{
double x[5];
}p[110];
int n;
double cal(struct point qaq)
{
double res=0;
for(int i=1;i<=n;i++)
{
double tmp=0;
for(int j=1;j<=3;j++)
tmp+=(qaq.x[j]-p[i].x[j])*(qaq.x[j]-p[i].x[j]);
res=max(res,sqrt(tmp));
}
return res;
}
struct point Cal(int cnt,struct point now)
{
if(cnt>=4) return now;
double l=-100000,r=100000;
struct point ans,tmpl,tmpr,ansl,ansr;
tmpl=now;tmpr=now;
while(feps<r-l)
{
double ll=(2*l+r)/3,rr=(l+2*r)/3;
tmpl.x[cnt]=ll;tmpr.x[cnt]=rr;
ansl=Cal(cnt+1,tmpl);
ansr=Cal(cnt+1,tmpr);
if(cal(ansl)>cal(ansr))
{
l=ll;
ans=ansl;
}
else
{
r=rr;
ans=ansr;
}
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=3;j++)
scanf("%lf",&p[i].x[j]);
struct point ans;
for(int i=1;i<=3;i++) ans.x[i]=0;
printf("%.15f\n",cal(Cal(1,ans)));
return 0;
}
模拟退火
等我学了吧…