HDU2215 ——Maple trees

Problem Description
There are a lot of trees in HDU. Kiki want to surround all the trees with the minimal required length of the rope . As follow,
HDU2215 ——Maple trees_第1张图片
To make this problem more simple, consider all the trees are circles in a plate. The diameter of all the trees are the same (the diameter of a tree is 1 unit). Kiki can calculate the minimal length of the rope , because it's so easy for this smart girl.
But we don't have a rope to surround the trees. Instead, we only have some circle rings of different radius. Now I want to know the minimal required radius of the circle ring. And I don't want to ask her this problem, because she is busy preparing for the examination.
As a smart ACMer, can you help me ?
HDU2215 ——Maple trees_第2张图片
 

Input
The input contains one or more data sets. At first line of each input data set is number of trees in this data set n (1 <= n <= 100), it is followed by n coordinates of the trees. Each coordinate is a pair of integers, and each integer is in [-1000, 1000], it means the position of a tree’s center. Each pair is separated by blank.
Zero at line for number of trees terminates the input for your program.
 

Output
Minimal required radius of the circle ring I have to choose. The precision should be 10^-2.
 

Sample Input
     
     
     
     
2 1 0 -1 0 0
 

Sample Output
     
     
     
     
1.50
 

Author
zjt
 

计算几何题,最小圆覆盖,这里我用的是随机增量法,期望为O(n)。
    先以第一个点为圆心,找到第一个不在圆内或圆上的点,以它为圆心,去找第二个不在圆内或圆上的点,以这两个点的中点为圆心,距离为直径,去找第三个不在圆上或者圆内的点,以这三个点形成的三角形的外心为圆心,遍历其他点,最后得到的就是覆盖所有点的最小的圆。

//最小圆覆盖——随机增量法,期望为O(n)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<map>
#include<vector>
#include<math.h>

using namespace std;

const double eps = 1e-8;
struct point
{
double x ,y;
}p[105];

double dist(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));//计算距离
}

//返回外心
point crosspoint(point p0, point p1, point p2)
{
point ret;
double a1 = p1.x - p0.x, b1 = p1.y - p0.y, c1 = (a1 * a1 + b1 * b1) / 2;
double a2 = p2.x - p0.x, b2 = p2.y - p0.y, c2 = (a2 * a2 + b2 * b2) / 2;
double d = a1 * b2 - a2* b1;
ret.x = p0.x + (c1 * b2 - c2 * b1) / d;
ret.y = p0.y + (a1 * c2 - a2 * c1) / d;
return ret;
}

double min_cover_circle(int n)
{
random_shuffle(p, p + n) ;//打乱顺序
point c = p[0];
double r = 0;
for (int i = 1; i < n; ++i)
{
if (dist(p[i], c) > r) //第一个点
{
c = p[i];
r = 0;
for (int j = 0; j < i; ++j)
{
if (dist(p[j], c) > r)
{
c.x = (p[i].x + p[j].x) / 2;
c.y = (p[i].y + p[j].y) / 2;
r=dist(p[j], c);
for (int k = 0; k < j; ++k)
{
if(dist(p[k], c) > r)
{
c = crosspoint(p[i], p[j], p[k]);
r = dist(c, p[k]);
}
}
}
}
}
}
return r;
}

int main()
{
int n;
while(~scanf("%d",&n) && n)
{
for (int i = 0; i < n; ++i)
{
scanf("%lf%lf",&p[i].x ,&p[i].y);
}
if(n == 1)
printf("0.50\n");//这题树本身也存在半径,而计算时用的是中心,所以输出时还要加上树的半径
else
{
double r = min_cover_circle(n);
printf("%.2lf\n", r + 0.50);
}
}
return 0;
}



你可能感兴趣的:(HDU2215 ——Maple trees)