题目链接:http://codeforces.com/gym/101981/attachments
题意:给你n个三维空间点(n<=100)要求找到一个离所有点最远的距离最小的点,并输出这个距离
思路:模拟退火,首先取一个值,代表答案点在的位置,然后暴力一遍所有的点,会得到里当前点最远的点是哪个
然后更新当前ans ,并且往这个最远的点移动,贪心,最后就是答案了
看代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<map> #include<cstdlib> using namespace std; typedef long long LL; const LL mod=1e9+7; const LL INF=1e9+7; const int maxn=1e2+50; const double StartT=50000;//初始温度 1000也可以过这道题 const double rate=0.99;//退火系数 一般0.97-0.99 const double eps=1e-6;//精度 可以在题目要求的小数点后面位数多加3左右 const double FINF=1e18; /** 没有算退火的复杂度 rate=0.98 T=1000 1026次 T=20000 1175次 T=50000 1220次 rate=0.99 T=50000 2452 **/ int N; struct Node { double x,y,z; Node(){} Node(double x1,double y1,double z1) { x=x1;y=y1;z=z1; } }a[maxn]; double dist(Node n1,Node n2) { return sqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y)+(n1.z-n2.z)*(n1.z-n2.z)); } void solve() { // int sum=0; double ans=FINF; // cout<<ans<<endl; double T=StartT; Node now=Node(0,0,0);//随机选取一个点 Node max_p=a[1];//离当前最远的点 while(T>eps) { // sum++; for(int i=1;i<=N;i++)//寻找里当前最远的点 { if(dist(a[i],now)>=dist(max_p,now)) { max_p=a[i]; } } ans=min(ans,dist(now,max_p)); now.x=(now.x+(max_p.x-now.x)*(T/StartT)); now.y=(now.y+(max_p.y-now.y)*(T/StartT)); now.z=(now.z+(max_p.z-now.z)*(T/StartT)); T=T*rate; } // cout<<"sum:"<<sum<<endl; printf("%.15lf\n",ans); } int main() { scanf("%d",&N); for(int i=1;i<=N;i++) { scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z); } solve(); return 0; }