hdu 1007 求最进点对的问题

Quoit Design

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 21673    Accepted Submission(s): 5552


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
   
   
   
   
2 0 0 1 1 2 1 1 1 1 3 -1.5 0 0 0 0 1.5 0
 

Sample Output
   
   
   
   
0.71 0.00 0.75
对于这个题我表示相当的无语,我在前面刚刚把最近点对的模板给写出来,这个我几乎就是直接把模板给贴上去就ac了。这个题目的题意非常简单,就是给一系列的点,然后求出最近的点对间的距离的一半。
代码:
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<cstring>

using namespace std;

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, i;
    double d;
    scanf("%d", &n);
    while (n) {
        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(b, a, n *sizeof(a[0]));
        qsort(b, n, sizeof(b[0]), cmp_y);
        d = closest(a, b, c, 0, n - 1);
        printf("%.2lf\n", d/2);注意求的是最近距离的一半。
        scanf("%d", &n);
    }
    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);
}



你可能感兴趣的:(hdu 1007 求最进点对的问题)