题目大意
空间最小球覆盖
思路
临滚粗前做点水题qwq
CODE
#define _CRT_SECURE_NO_WARNINGS
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 1e15
#define EPS 1e-7
#define MAX 100
using namespace std;
struct PointIII{
double x, y, z;
PointIII(const double &_, const double &__, const double &___):x(_), y(__), z(___) {}
PointIII() {}
PointIII operator +(const PointIII &a)const {
return PointIII(x + a.x, y + a.y, z + a.z);
}
PointIII operator *(const double &a)const {
return PointIII(x * a, y * a, z * a);
}
void Read() {
scanf("%lf%lf%lf", &x, &y, &z);
}
}point[MAX];
int points;
double ans, fin;
inline unsigned int Rand()
{
return rand() * rand();
}
inline double Calc(const PointIII &p1, const PointIII &p2)
{
return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z));
}
void SA()
{
double T = 100.0;
double x = 0, y = 0, z = 0;
for(int i = 1; i <= points; ++i)
x += point[i].x, y += point[i].y, z += point[i].z;
PointIII now(x / points, y / points, z / points);
ans =INF;
while(T > EPS) {
int p = 1;
for(int i = 2; i <= points; ++i)
if(Calc(now, point[i]) > Calc(now, point[p]))
p = i;
double r = Calc(now, point[p]);
ans = min(ans, r);
now.x += (point[p].x - now.x) / r * T;
now.y += (point[p].y - now.y) / r * T;
now.z += (point[p].z - now.z) / r * T;
T *= .98;
}
}
int main()
{
while(scanf("%d", &points), points) {
for(int i = 1; i <= points; ++i)
point[i].Read();
SA();
printf("%.5f\n", ans);
}
return 0;
}
时间: 2024-11-10 03:56:59