我使用的是二分法。当我写如下代码时,我的第三个数据点会错误,但当我把第3行的EPS从1e-10改为1e-5时,我通过了本题。期间我一直在试图优化精度,但从来没有奏效过。最后突发奇想会不会是写数据生成器的答卷精度不够高,自己就把精度调低了,结果反而AC了。
#include <iostream>
const int MAXN(1002);
const double EPS(1e-10);
using namespace std;
int n, w[MAXN], wx[MAXN], wy[MAXN];
inline double sq(double x) { return x * x; }
inline double fisr(double x) {
using ull = unsigned long long;
ull b(*(ull*)&x);
double halfx(0.5 * x);
b = 0x5FE7000000000000ULL - (b >> 1); // wtf?
x = *(double*)(&b);
x *= (1.5 - halfx * x * x);
x *= (1.5 - halfx * x * x);
x *= (1.5 - halfx * x * x); // this can be removed.
x *= (1.5 - halfx * x * x); // this can be removed.
return x;
}
int main() {
double xmin(1e4), xmax(-1e4), ymin(1e4), ymax(-1e4);
scanf("%d", &n);
for (int i(1); i <= n; ++i) {
scanf("%d%d%d", wx + i, wy + i, w + i);
xmin = min(xmin, (double)wx[i]);
xmax = max(xmax, (double)wx[i]);
ymin = min(ymin, (double)wy[i]);
ymax = max(ymax, (double)wy[i]);
}
xmin -= EPS; xmax += EPS; ymin -= EPS; ymax += EPS;
double xmid, ymid, fx, fy;
while (xmax - xmin > EPS || ymax - ymin > EPS) {
xmid = (xmin + xmax) * 0.5;
ymid = (ymin + ymax) * 0.5;
fx = 0.0;
fy = 0.0;
for (int i(1); i <= n; ++ i) {
double tmp(fisr(sq(wx[i] - xmid) + sq(wy[i] - ymid)) * w[i]);
if (sq(wx[i] - xmid) > EPS)
fx += (wx[i] - xmid) * tmp;
if (sq(wy[i] - ymid) > EPS)
fy += (wy[i] - ymid) * tmp;
}
if (fx > abs(fy) - EPS)
xmin = xmid;
if (fx < EPS - abs(fy))
xmax = xmid;
if (fy > abs(fx) - EPS)
ymin = ymid;
if (fy < EPS - abs(fx))
ymax = ymid;
// printf("%6lf~%6lf %6lf~%6lf\n", xmin, xmax, ymin, ymax);
}
printf("%.3lf %.3lf", xmid, ymid);
return 0;
}