最近点对,分治法。
开始写错了,居然A掉了><。。。而且居然排第一版了><。。。。无语啦。。。
需要先对x排序,然后分治的时候对y排序才对。精度判断WA了多次,最后找到,getmin如果改成小于等于就过了,或者不加精度判断也行,小于的话死活过不去,我把eps开到15次方才过><。。。郁闷
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> using namespace std; const int MAX = 100010; const double D_MAX = 1e50; const double eps = 1e-15; struct point{ double x,y; }; point p[MAX]; bool dy(double x,double y) // x > y { return x > y + eps; } bool xy(double x,double y) // x < y { return x < y - eps; } bool dyd(double x,double y) // x >= y { return x > y - eps; } bool xyd(double x,double y) // x <= y { return x < y + eps; } bool dd(double x,double y) // x == y { return fabs( x - y ) < eps; } double disp2p(point a,point b) { return sqrt( (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) ); } double getmin(double a,double b) { return xy(a,b) ? a : b; } bool cmp(point a,point b) { if( dd(a.x,b.x) ) return xy(a.y,b.y); return xy(a.x,b.x); } bool cmpy(point a,point b) { if( dd(a.y,b.y) ) return xy(a.x,b.x); return xy(a.y,b.y); } point y[MAX]; double nearpot(int l,int r) { if( l == r ) return D_MAX; if( l == r-1 ) return disp2p(p[l],p[r]); if( l == r-2 ) return getmin( getmin(disp2p(p[l],p[l+1]),disp2p(p[l],p[l+2])), disp2p(p[l+1],p[l+2]) ); int mid = (l+r)>>1; double ans = getmin( nearpot(l,mid), nearpot(mid+1,r) ); int len = 0; for(int i=mid; i>=l && xy(p[mid].x-p[i].x,ans); i--) y[len++] = p[i]; for(int i=mid+1; i<=r && xy(p[i].x-p[mid].x,ans); i++) y[len++] = p[i]; sort(y,y+len,cmpy); for(int i=0; i<len-1; i++) for(int k=i+1; k<len; k++) { if( dyd(y[k].y-y[i].y,ans) ) break; ans = getmin(ans,disp2p(y[i],y[k])); } return ans; } int main() { int n; while( ~scanf("%d",&n) && n ) { for(int i=0; i<n; i++) scanf("%lf %lf",&p[i].x,&p[i].y); sort(p,p+n,cmp); double ans = nearpot(0,n-1); printf("%.2lf/n",ans/2.0); } return 0; }