给出n(n<=100)个点,找平面上一个点使得这个点到所有点的距离最小。
怎么搞,依次找每个点?不行
二分?很明显没有单调性质
所以就乱搞!!
用一个NP的算法:
先在平面上找一个点,然后确定一个半径,在这个圆上找一个点,看是否更优,是就更新x,y.半径要不断缩小。
这种做法带有很强的随机性,但是在一定精度下他是对的。
这里我们就需要考虑这样一个问题:半径缩小的越慢,找到的点越精确,但同时速度也就越慢。我们就需要在精度和时间的确立中找到一个平衡位置。
这就是传说中的随机算法:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
const int maxn=105;
using namespace std;
int n;
int xi[maxn],yi[maxn];
double sum(double x,double y)
{
double ans=0;
for(int i=1;i<=n;i++)
{
ans+=sqrt((x-xi[i])*(x-xi[i])+(y-yi[i])*(y-yi[i]));
}
return ans;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)scanf("%d%d",&xi[i],&yi[i]);
double step=100000;
double x=xi[1],y=yi[1];
while(step>1e-9)
{
double rad=rand()%360+1;
double nx=x+step*cos(rad);
double ny=y+step*sin(rad);
if(sum(nx,ny)<sum(x,y))
{
x=nx;
y=ny;
}
step*=0.99;
}
printf("%.0f\n",sum(x,y));
}
return 0;
}