爬山算法
例题
P4035 [JSOI2008] 球形空间产生器 - 洛谷
给出 \(n+1\) 个 \(n\) 维的点, 求他们所在球的球心
代码
| C++ |
|---|
| #include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int __OneWan_2024 = [](){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
return 0;
}();
double a[15][15], ans[15], dist[15], cans[15];
int main() {
int n;
cin >> n;
for (int i = 1 ; i <= n + 1 ; i++) {
for (int j = 1 ; j <= n ; j++) {
cin >> a[i][j];
ans[j] += a[i][j];
}
}
for (int i = 1 ; i <= n ; i++) {
ans[i] /= n + 1;
}
auto get = [&]() {
double res = 0;
for (int i = 1 ; i <= n + 1 ; i++) {
dist[i] = cans[i] = 0;
for (int j = 1 ; j <= n ; j++) {
dist[i] += (a[i][j] - ans[j]) * (a[i][j] - ans[j]);
}
dist[i] = sqrt(dist[i]);
res += dist[i];
}
res /= n + 1;
for (int i = 1 ; i <= n + 1 ; i++) {
for (int j = 1 ; j <= n ; j++) {
cans[j] += (dist[i] - res) * (a[i][j] - ans[j]) / res;
}
}
};
auto sa = [&]() {
for (double t = 50000 ; t >= 1e-4 ; t *= 0.99995) {
get();
for (int i = 1 ; i <= n ; i++) {
ans[i] += cans[i] * t;
}
}
};
sa();
for (int i = 1 ; i <= n ; i++) {
cout << fixed << setprecision(3) << ans[i] << " ";
}
return 0;
}
|