给出n(n<=100)个点,找平面上一个点使得这个点到所有点的距离最小。
如果是二分,没有单调性;如果是遍历,不准确,只能用随机算法
#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
//#define DEBUG
#define RI register int
#define PII pair<int, int>
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define PI acos(-1.0)
using namespace std;
int n;
double xi[105], yi[105];
double sum(double dx, double dy)
{
double res = 0;
for (int i = 1; i <= n; i++)
res += sqrt((xi[i] - dx) * (xi[i] - dx) + (yi[i] - dy) * (yi[i] - dy));
return res;
}
int main()
{
#ifdef DEBUG
freopen("input.in", "r", stdin);
freopen("output.out", "w", stdout);
printf("Time cost : %lf s\n", (double)clock() / CLOCKS_PER_SEC);
#endif
srand((size_t)time(NULL));
cin >> n;
for (int i = 1; i <= n; i++)
cin >> xi[i] >> yi[i];
//1.先设定初始温度T,降温系数delt,降温下界eps
double T = 1000000;
double delt = 0.997;
double eps = 1e-14;
//2.随机产生一个合法初始点(当然也可以自己设定)
double x = xi[1], y = yi[1];
while (T > eps)
{
//3.降温
//--基于当前的点产生一个值.温度越高,产生的值的波动的范围就越大;温度越低,产生的值的波动的范围就越小;
double rad = (rand() % 1000 + 1.0) / 1000.0 * 2 * PI;
double dx = x + cos(rad) * T;
double dy = y + sin(rad) * T;
//--如果新产生的值比当前的值更好,那么把当前的点更新为那个更优的值
if (sum(dx, dy) < sum(x, y))
{
x = dx;
y = dy;
}
T *= delt;
}
printf("%.0f\n", sum(x, y));
}