## Quoit Design

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 136 Accepted Submission(s): 77

Problem Description

Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.
In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring.

Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0.

Input

The input consists of several test cases. For each case, the first line contains an integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0.

Output

For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places.

Sample Input

20 01 121 11 13-1.5 00 00 1.50

Sample Output

0.710.000.75

Author

CHEN, Yue

Source

ZJCPC2004

Recommend

JGShining

最小点对问题。所谓的最小点对问题就是,在n个点中找到2个点间的最短距离。这种题有两种思路：

1）直接暴力。看一看数据规模,n都在100000左右了，O(n^2)的算法，不出意外,会TLE。

2）分治。这道题用的是吉林大学的模板。直接套进去就行了。

``````#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>

using namespace std;

/**
* 求n个点中,2个点之间的最短距离。
* 1)直接暴力。肯定会TLE
* 2)使用吉林大学的模板
*/
const int N = 100005;
const double MAX = 10e100, eps = 0.00001;
struct Point {
double x, y;
int index;
};
Point a[N], b[N], c[N];
double closest(Point *, Point *, Point *, int, int);
double dis(Point, Point);
int cmp_x(const void *, const void*);
int cmp_y(const void *, const void*);
int merge(Point *, Point *, int, int, int);
inline double min(double, double);

int main(){
int n;
while(scanf("%d",&n)!=EOF,n){
int i;
for(i = 0 ; i < n ; ++i){
scanf("%lf %lf",&a[i].x,&a[i].y);
}
qsort(a,n,sizeof(a[0]),cmp_x);
for(i = 0 ; i < n ; ++i){
a[i].index = i;
}

/**
* memcpy(目标地址,起始地址,n个字节)
* 作用:从起始地址拷贝n个字节到目标地址
* 头文件: 尽量把 <cstring>引入
*
*/
memcpy(b,a,n*sizeof(a[0]));

qsort(b,n,sizeof(b[0]),cmp_y);

double ans = closest(a,b,c,0,n-1);

printf("%.2lf\n",ans/2);
}

return 0;
}

double closest(Point a[], Point b[], Point c[], int p, int q) {
if (q - p == 1){
return dis(a[p], a[q]);
}
if (q - p == 2) {
double x1 = dis(a[p], a[q]);
double x2 = dis(a[p + 1], a[q]);
double x3 = dis(a[p], a[p + 1]);
if (x1 < x2 && x1 < x3){
return x1;
}
else if (x2 < x3){
return x2;
}
else{
return x3;
}
}
int i, j, k, m = (p + q) / 2;
double d1, d2;
for (i = p, j = p, k = m + 1; i <= q; i++){
if (b[i].index <= m){
c[j++] = b[i];
}
// 数组c 左半部保存划分后左部的点,  且对y 是有序的.
else{
c[k++] = b[i];
}
}
d1 = closest(a, c, b, p, m);
d2 = closest(a, c, b, m + 1, q);
double dm = min(d1, d2);
// 数组c 左右部分分别是对y 坐标有序的,  将其合并到b.
merge(b, c, p, m, q);
for (i = p, k = p; i <= q; i++){
if (fabs(b[i].x - b[m].x) < dm){
c[k++] = b[i];
}
}
// 找出离划分基准左右不超过dm 的部分,  且仍然对y 坐标有序.
for (i = p; i < k; i++){
for (j = i + 1; j < k && c[j].y - c[i].y < dm; j++) {
double temp = dis(c[i], c[j]);
if (temp < dm){
dm = temp;
}
}
}
return dm;
}
double dis(Point p, Point q) {
double x1 = p.x - q.x, y1 = p.y - q.y;
return sqrt(x1 * x1 + y1 * y1);
}
int merge(Point p[], Point q[], int s, int m, int t) {
int i, j, k;
for (i = s, j = m + 1, k = s; i <= m && j <= t;) {
if (q[i].y > q[j].y){
p[k++] = q[j], j++;
}else{
p[k++] = q[i], i++;
}
}
while (i <= m){
p[k++] = q[i++];
}
while (j <= t){
p[k++] = q[j++];
}

memcpy(q + s, p + s, (t - s + 1) * sizeof(p[0]));
return 0;
}
int cmp_x(const void *p, const void *q) {
double temp = ((Point*) p)->x - ((Point*) q)->x;
if (temp > 0){
return 1;
}
else if (fabs(temp) < eps){
return 0;
}
else{
return -1;
}
}
int cmp_y(const void *p, const void *q) {
double temp = ((Point*) p)->y - ((Point*) q)->y;
if (temp > 0){
return 1;
}
else if (fabs(temp) < eps){
return 0;
}
else{
return -1;
}
}
inline double min(double p, double q) {
return (p > q) ? (q) : (p);
}``````