一道平面分治的板子题(做之前刚学会平面分治,太菜了)
把所有点按照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 }