解题思路:
给出空间内的n个点,找出覆盖这n个点的最小球的半径。用模拟退火来做。
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <queue> #include <stack> #include <map> #include <cmath> #include <set> #define LL long long using namespace std; const int MAXN = 50; const double eps = 1e-6; struct Point { double x, y, z; Point(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) { } }; Point operator - (Point A, Point B) { return Point(A.x - B.x, A.y - B.y, A.z - B.z); } double dis(Point A, Point B) { double x = A.x - B.x; double y = A.y - B.y; double z = A.z - B.z; return sqrt(x * x + y * y + z * z); } int n; Point p[MAXN]; double SA(Point start) { double delta = 100.0; double ans = 1e20; while(delta > eps) { int d = 0; for(int i=0;i<n;i++) { if(dis(p[i], start) > dis(p[d], start)) d = i; } double r = dis(start, p[d]); ans = min(ans, r); start.x += (p[d].x - start.x) / r * delta; start.y += (p[d].y - start.y) / r * delta; start.z += (p[d].z - start.z) / r * delta; delta *= 0.98; } return ans; } int main() { int T, kcase = 1; //scanf("%d", &T); while(scanf("%d", &n) && n) { //scanf("%d", &n); for(int i=0;i<n;i++) scanf("%lf%lf%lf", &p[i].x, &p[i].y, &p[i].z); printf("%.5lf\n", SA(Point(0,0,0))); } return 0; }
POJ 2069 Super Star(模拟退火,最小球覆盖)
原文地址:http://blog.csdn.net/moguxiaozhe/article/details/44921559