UVA

一道平面分治的板子题(做之前刚学会平面分治,太菜了)

把所有点按照x排序后,分成左半边的最近距离和右半边的最近距离,再以中点为圆心,目前的最近距离为半径,做这个圆内的枚举,求最短距离。

注意:sqrt()里面的数如果是int类型会比double类型慢,如果次数多了会T

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node{
 4     double x,y;
 5 }a[10005];
 6 bool cmp(node& a, node& b){
 7     return a.x < b.x;
 8 }
 9 double dis(int i,int j){
10     return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
11 }
12 double erfen(int l,int r){
13     if (l>r) return 40004;
14     int mid=(l+r)>>1;
15     int st=mid,ed=mid;
16     double d=std::min(erfen(l,mid-1),erfen(mid+1,r));
17     while (st>=l && a[st].x+d>a[mid].x) st--;
18     while (ed<=r && a[ed].x-d<a[mid].x) ed++;
19     for (int i=st+1; i<ed; i++){
20         for (int j=i+1; j<ed; j++){
21             d=std::min(dis(i,j),d);
22         }
23     }
24     return d;
25 }
26 int main(){
27     int n;
28     while (scanf("%d",&n)){
29         if (n==0) break;
30         for (int i=1; i<=n; i++){
31             scanf("%lf%lf",&a[i].x,&a[i].y);
32         }
33         sort(a+1,a+1+n,cmp);
34         double ret=erfen(1,n);
35         if (ret>10000) printf("INFINITY
");
36         else printf("%.4f
",ret);
37     }
38 }
View Code
原文地址:https://www.cnblogs.com/i-caigou-TT/p/14349663.html