hdu 1007 Quoit Design (经典分治 求最近点对)

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

给你平面上n个点,让你找最近的2个点的距离的一半

经典的分治问题,我们现将点按照x坐标排序,先处理前一半的答案,再处理后一半的答案,两个取最小ans

现在还没完呢,万一一个点在左半边另一个点在右半边呢?这样我们就要更新答案了.我们注意到这样的点肯定满足到中心的点的距离不超过ans

我们暴力搞出这些点,这些点是有可能来更新ans的,我们是不是要将这些点n^2算距离更新呢?这样显然是超时的

我们将这些点按y坐标排序,我们对于第1个点开始求它与第2~cnt个点的y坐标的差值,一旦这个差值大于ans就不用再去比较后面的点了,我们再从第2个点求它与第3~cnt个点的y坐标差,以此类推

这样及时的break就优化了......

谁信啊!!!!其实这涉及到一个点周围能够更新ans的点最多有6个,否则上面ans就不是答案了

代码如下:

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4 const int maxn = 1100000;
 5 struct point
 6 {
 7     double x,y;
 8 }p[maxn];
 9 int a[maxn];
10 double dis (point q1,point q2)
11 {
12     return sqrt((q1.x-q2.x)*(q1.x-q2.x)+(q1.y-q2.y)*(q1.y-q2.y));
13 }
14 bool cmpx (point q1,point q2)
15 {
16     return q1.x<q2.x;
17 }
18 bool cmpy (int q1,int q2)
19 {
20     return p[q1].y<p[q2].y;
21 }
22 int n;
23 double calc (int l,int r)
24 {
25     if (r==l+1)
26         return dis(p[l],p[r]);
27     else if (r==l+2)
28         return min(dis(p[l],p[l+1]),min(dis(p[l+1],p[r]),dis(p[l],p[r])));
29     else{
30         int mid = (l+r)/2;
31         double ans = min(calc(l,mid),calc(mid+1,r));
32         int cnt = 0;
33         for (int i=l;i<=r;++i){
34             if (p[i].x>=p[mid].x-ans&&p[i].x<=p[mid].x+ans)
35                 a[cnt++]=i;
36         }
37         sort(a,a+cnt,cmpy);
38         for (int i=0;i<cnt;++i){
39             for (int j=i+1;j<cnt;++j){
40                 if (p[a[j]].y-p[a[i]].y>=ans) break;
41                 else{
42                     ans = min(ans,dis(p[a[i]],p[a[j]]));
43                 }
44             }
45         }
46         return ans;
47     }
48 }
49 int main()
50 {
51     //freopen("de.txt","r",stdin);
52     while (~scanf("%d",&n)){
53         if (n==0) break;
54         for (int i=0;i<n;++i){
55             scanf("%lf%lf",&p[i].x,&p[i].y);
56         }
57         sort(p,p+n,cmpx);
58         double ans = calc(0,n-1);
59         printf("%.2f\n",ans/2);
60     }
61     return 0;
62 }

精髓就是通过不断二分从指数上将复杂度降下来

时间: 2024-10-10 02:03:55

hdu 1007 Quoit Design (经典分治 求最近点对)的相关文章

HDU 1007 Quoit Design (分治)

Quoit Design 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 ri

HDU ACM 1007 Quoit Design 分治法求最近点对

题意:给n个点的坐标,求距离最近的一对点之间距离的一半. 分析:分治法求最近点对. #include<iostream> #include<algorithm> #include<cmath> using namespace std; #define N 100005 double min(double a,double b) { return a<b?a:b; } struct POINT { double x,y; }; POINT point[N],*px[

HDU 1007 Quoit Design | 平面分治

暂鸽 #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define N 100010 using namespace std; void chkmin(double x,double y) {if (x>y) x=y;} int n; struct point { double x,y; point(){}; point(double _x,double _

hdu 1007 Quoit Design 分治求最近点对

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 29344    Accepted Submission(s): 7688 Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat

HDU 1007 Quoit Design【计算几何/分治/最近点对】

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 58566    Accepted Submission(s): 15511 Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat

分治算法应用-最近点对的最小距离-hdu 1007 Quoit Design

题目描述 给出二维平面上的n个点,求其中最近的两个点的距离的一半. 输入包含多组数据,每组数据第一行为n,表示点的个数:接下来n行,每行一个点的坐标.当n为0时表示输入结束,每组数据输出一行,为最近的两个点的距离的一半. 输入样例: 2 0 0 1 1 2 1 1 1 1 3 -1.5 0 0 0 0 1.5 0 输出样例: 0.71 0.00 0.75 题目解析: 采用分治的思想,把n个点按照x坐标进行排序,以坐标mid为界限分成左右两个部分,对左右两个部分分别求最近点对的距离,然后进行合并.

分治 [HDU 1007] Quoit Design

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 33577    Accepted Submission(s): 8800 Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat

HDU 1007 Quoit Design

Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 130 Accepted Submission(s): 72   Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings a

HDU 1007 Quoit Design(二分+浮点数精度控制)

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 47104    Accepted Submission(s): 12318 Problem Description Have you ever played quoit in a playground? Quoit is a game in which fla