Maple trees
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1939 Accepted Submission(s): 607
Total Submission(s): 1939 Accepted Submission(s): 607
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,
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 ?
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 ?
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.
Zero at line for number of trees terminates the input for your program.
Minimal required radius of the circle ring I have to choose. The precision should be 10^-2.
2 1 0 -1 0 0
1.50
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2215
题目大意:给n个直径为1的圆的圆心,求对这些圆的最小覆盖圆的半径
题目分析:先求凸包,注意特判一个点和求出的纯净凸包只含两个点的情况,若不是则枚举凸包上的任意三点,求包含这三点的最小圆半径,取所有半径的最大值加0.5即为答案,若三点构成的三角形是钝角三角形则包含这个三角形的最小圆是以钝角对边的中点为圆心,半径为对边一半的圆,故此时半径即为钝角对边的一半,若三点构成的三角形不是钝角三角形,则根据正弦定理a/sinA = b/sinB = c/sinC = 2R,S = bcsinA/2,带入得R = abc/4S,S直接用叉积可以算出来
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int const MAX = 105;
struct POINT {
int x, y;
}p[MAX], stk[MAX], base;
int n, top;
double getDist(POINT p1, POINT p2) {
return sqrt(1.0 * (p2.x - p1.x) * (p2.x - p1.x) + 1.0 * (p2.y - p1.y) * (p2.y - p1.y));
}
int getCross(POINT p0, POINT p1, POINT p2) {
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
bool cmp(POINT p1, POINT p2) {
if (getCross(base, p1, p2) == 0) {
return getDist(base, p1) < getDist(base, p2);
}
if (getCross(base, p1, p2) > 0) {
return true;
}
return false;
}
void getBase() {
scanf("%d %d", &p[0].x, &p[0].y);
base.x = p[0].x;
base.y = p[0].y;
int pos = 0;
for (int i = 1; i < n; i ++) {
scanf("%d %d", &p[i].x, &p[i].y);
if (p[i].y < base.y || (p[i].y == base.y && p[i].x < base.x)) {
base.x = p[i].x;
base.y = p[i].y;
pos = i;
}
}
swap(p[0], p[pos]);
}
void getConvex() {
stk[0] = p[0];
stk[1] = p[1];
top = 1;
for (int i = 2; i < n; i ++) {
while (top > 0 && getCross(stk[top - 1], stk[top], p[i]) <= 0) {
top --;
}
stk[++ top] = p[i];
}
}
bool judge(double a, double b, double c){
return a * a + b * b < c * c;
}
double calR(POINT p0, POINT p1, POINT p2) {
double p0p1 = getDist(p0, p1);
double p0p2 = getDist(p0, p2);
double p1p2 = getDist(p1, p2);
if (judge(p0p1, p0p2, p1p2) || judge(p0p1, p1p2, p0p2) || judge(p0p2, p1p2, p0p1)) {
return max(p0p1, max(p0p2, p1p2)) / 2.0;
}
double S = fabs(getCross(p0, p1, p2)) / 2.0;
return p0p1 * p0p2 * p1p2 / 4.0 / S;
}
int main() {
while(scanf("%d", &n) && n) {
getBase();
if (n == 1) {
printf("0.50\n");
continue;
}
sort(p + 1, p + n, cmp);
getConvex();
if (top == 1) {
printf("%.2f\n", getDist(stk[0], stk[1]) / 2.0 + 0.5);
continue;
}
double ans = 0;
for (int i = 0; i <= top; i ++) {
for (int j = i + 1; j <= top; j ++) {
for (int k = j + 1; k <= top; k ++) {
ans = max(ans, calR(stk[i], stk[j], stk[k]));
}
}
}
printf("%.2f\n", ans + 0.5);
}
}