题目链接:http://poj.org/problem?id=2069
题意:求一个半径最小的球,使得它可以包围住所有点。
模拟退火,圆心每次都去找最远那个点,这样两点之间的距离就是半径,那么接下来移动的方向肯定就是朝着这个最远点移动,保证比例相同且在球内的情况下移动。
不看题解想不到,这个东西有点难啊。。。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <cassert> 8 #include <cstdio> 9 #include <bitset> 10 #include <vector> 11 #include <deque> 12 #include <queue> 13 #include <stack> 14 #include <ctime> 15 #include <set> 16 #include <map> 17 #include <cmath> 18 using namespace std; 19 20 typedef struct P { 21 double x, y, z; 22 }P; 23 const double inf = 1e90; 24 const double eps = 1e-7; 25 const double delta = 0.98; 26 const int maxn = 55; 27 P p[maxn]; 28 int n; 29 30 double dist(P a, P b) { 31 double p = a.x - b.x; 32 double q = a.y - b.y; 33 double r = a.z - b.z; 34 return sqrt(p*p+q*q+r*r); 35 } 36 37 int main() { 38 // freopen("in", "r", stdin); 39 while(~scanf("%d", &n) && n) { 40 for(int i = 0; i < n; i++) { 41 scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z); 42 } 43 double t = 100; 44 double ret = inf; 45 P pos = {0, 0, 0}; 46 while(t > eps) { 47 int k = 0; 48 for(int i = 0; i < n; i++) { 49 if(dist(pos, p[i]) > dist(pos, p[k])) { 50 k = i; 51 } 52 } 53 double d = dist(pos, p[k]); 54 ret = min(ret, d); 55 pos.x += (p[k].x - pos.x) / d * t; 56 pos.y += (p[k].y - pos.y) / d * t; 57 pos.z += (p[k].z - pos.z) / d * t; 58 t *= delta; 59 } 60 printf("%.5lf ", ret); 61 } 62 return 0; 63 }