题目大意:给你$n$个点坐标,要你求出圆心
题解:随机化,可以随机一个点当圆心,然后和每个点比较,求出平均距离$r$,如果到这个点的距离大于$r$,说明离这个点远了,就给圆心施加一个向这个点的力;若小于$r$,说明近了,就施加一个远离这个点的力。所有点比较完后,把假设的圆心按合力方向移动一个距离,距离和当前温度有关。时间越久,温度越低
卡点:第$8$个点精度总是不够,拼命调参,调好后第$3$个点就$Tle$了,最后卡时过的
C++ Code:
#include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <ctime> #define maxn 12 int n; struct Point { double x[maxn], w; inline friend Point operator + (const Point &lhs, const Point &rhs) { Point res; for (register int i = 0; i < n; i++) res.x[i] = lhs.x[i] + rhs.x[i]; return res; } inline friend Point operator - (const Point &lhs, const Point &rhs) { Point res; for (register int i = 0; i < n; i++) res.x[i] = lhs.x[i] - rhs.x[i]; return res; } inline void operator /= (const int &rhs) { for (register int i = 0; i < n; i++) x[i] /= rhs; } } s[maxn], ans; inline double sqr(double x) {return x * x;} inline double abs(const Point &O) { double res = 0; for (int i = 0; i < n; i++) res += sqr(O.x[i]); return sqrt(res); } inline double dis(Point O) { double res = 0; for (int i = 0; i <= n; i++) res += abs(O - s[i]); return res; } const double ST = 5000, delT = 0.99995, eps = 1e-5; const int Tim = 1, __Tim = 250000; double V[maxn]; void SA() { double T = ST; while (T > eps) { double sum = dis(ans) / (n + 1); for (int i = 0; i < n; i++) { V[i] = 0; for (int j = 0; j <= n; j++) { V[i] += (abs(ans - s[j]) - sum) * (s[j].x[i] - ans.x[i]); } V[i] /= n + 1; } for (int i = 0; i < n; i++) { ans.x[i] += T * V[i]; } T *= delT; } for (int Tim = 0; Tim < __Tim && 1. * clock() / CLOCKS_PER_SEC < .9; Tim++) { double sum = dis(ans) / (n + 1); for (int i = 0; i < n; i++) { V[i] = 0; for (int j = 0; j <= n; j++) { V[i] += (abs(ans - s[j]) - sum) * (s[j].x[i] - ans.x[i]); } V[i] /= n + 1; } for (int i = 0; i < n; i++) { ans.x[i] += T * V[i]; } } } int main() { scanf("%d", &n); for (int i = 0; i <= n; i++) { for (int j = 0; j < n; j++) scanf("%lf", s[i].x + j); ans = ans + s[i]; } ans /= n + 1; for (int i = 0; i < Tim; i++) SA(); for (int i = 0; i < n; i++) { printf("%.3lf", ans.x[i]); putchar(i == n - 1 ? ' ' : ' '); } return 0; }