Link
题意:给n个点,问覆盖这n个点的最小的圆的半径和圆心坐标是多少
两种方法;
1, 增量法,
O
(
n
2
)
O(n^2)
O(n2) Link
2 , 模拟退火
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<double, double> PDD;
int n;
PDD q[502];
double r;
PDD ans;
double get_dist(PDD a, PDD b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return dx * dx + dy * dy;
}
int get_pos(PDD p)
{
double tmp = 0;
int pos = 0;
for(int i = 1; i <= n; i++)
{
double dis = get_dist(p, q[i]);
if(dis > tmp)
{
pos = i;
tmp = dis;
}
}
if(tmp < r)
{
ans = p;
r = tmp;
}
//cout << pos << endl;
return pos;
}
double rand(double l ,double r)
{
return (double)rand() / RAND_MAX * (r - l) + l;
}
void simulate_annual()
{
PDD cur;
cur.x = 0, cur.y = 0;
for(double i = 1; i > 1e-8; i *= 0.99)
{
int pos = get_pos(cur); // 朝着最远的那个点运动
cur.x += (q[pos].x - cur.x) * i;
cur.y += (q[pos].y - cur.y) * i;
}
}
signed main()
{
while(~scanf("%d", &n) && n != 0)
{
r = 1e8;
for(int i = 1; i <= n; i++)
{
scanf("%lf%lf", &q[i].x, &q[i].y);
}
simulate_annual();
printf("%.2lf %.2lf %.2lf\n", ans.x, ans.y, sqrt(r));
}
return 0;
}