zoj 2107
2012-05-21 15:19
253 查看
这题做了很久,一直都是1秒多,真不知道他们300ms是怎么做出来的。看了网上的代码,大部分都是O(nlgnlgn),于是绞尽脑汁,写了个O(nlgn)的代码,但是时间上没有显著地提高。
/** * O(nlogn) * zoj_2107 **/ #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; int const MAXN = 100010; double const eps = 1e-20; struct Point { double x, y; }; int n; Point toy[MAXN]; int yarr[MAXN]; int buffer[2*MAXN]; inline bool Dxlessy( double x, double y ) { return x+eps < y; } inline bool Dxequaly( double x, double y ) { return fabs(x-y)<eps; } inline double Dmin( double x, double y ) { if ( Dxlessy( x, y ) ) return x; return y; } bool pcmp( Point const& pa, Point const& pb ) { if ( Dxlessy( pa.x, pb.x ) ) return true; if ( Dxequaly( pa.x, pb.x ) && Dxlessy( pa.y, pb.y ) ) return true; return false; } bool ycmp( int a, int b ) { if ( Dxlessy( toy[a].y, toy[b].y ) ) return true; if ( Dxequaly( toy[a].y, toy[b].y ) && Dxlessy( toy[a].x, toy[b].x ) ) return true; return false; } inline double PointDist( Point const& a, Point const& b ) { return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) ); } double NearestP( int start, int end, int begin ) { int cnt = end-start+1; double dist; if ( 2 == cnt ) { return PointDist( toy[start], toy[end] ); } if ( 3 == cnt ) { dist = Dmin( PointDist( toy[start], toy[start+1] ), PointDist( toy[start+1], toy[end] ) ); dist = Dmin( dist, PointDist( toy[start], toy[end] ) ); return dist; } int le, i, j, a, b, k; double x0, d1, d2; le = start+(cnt>>1)-1; x0 = toy[le].x; a = start; b = le+1; for ( i = begin; i < begin+cnt; ++ i ) { if ( buffer[i] <= le ) //left part yarr[a++] = buffer[i]; else yarr[b++] = buffer[i]; } memcpy( buffer+begin+cnt, yarr+start, (cnt>>1)*sizeof(int) ); d1 = NearestP( start, le, begin+cnt ); //yarr[ start, le ] if ( d1 < eps ) return 0.0; memcpy( buffer+begin+cnt, yarr+le+1, (cnt-(cnt>>1))*sizeof(int) ); d2 = NearestP( le+1, end, begin+cnt ); //yarr[ le+1, end ] if ( d2 < eps ) return 0.0; dist = Dmin( d1, d2 ); a = start; for ( i = begin; i < begin+cnt; ++ i ) { if ( !Dxlessy( toy[ buffer[i] ].x, x0-dist ) && !Dxlessy( x0+dist, toy[ buffer[i] ].x ) ) yarr[a++] = buffer[i]; } for ( i = start; i < a-1; ++ i ) { b = i+8>a ? a : i+8; for ( j = i+1; j < b; ++ j ) { dist = Dmin( dist, PointDist( toy[ yarr[i] ], toy[ yarr[j] ] ) ); } } return dist; } int main() { int i; double result; while ( scanf("%d", &n) != EOF ) { if ( 0 == n ) break; for ( i = 0; i < n; ++ i ) { scanf("%lf%lf", &toy[i].x, &toy[i].y ); buffer[i] = i; } sort( toy, toy+n, pcmp ); sort( buffer, buffer+n, ycmp ); result = NearestP( 0, n-1, 0 ); printf("%.2lf\n", result/2.0); } return 0; }
相关文章推荐
- ZOJ2107——Quoit Design&&HDU1007——Quoit Design
- ZOJ 2107 HDU 1007 Quoit Design(最近点对)
- 最近点对,zoj 2107,hdu1007
- zoj 2107 Quoit Design(最近点对)
- zoj 2107 Quoit Design(平面最近点对)
- zoj 2107 Quoit Design(最近点对)
- hdu 1007 zoj 2107 Quoit Design 求平面最近点对 分治法
- ACM-计算几何之Quoit Design——hdu1007 zoj2107
- zoj 2107 最近点对
- zoj 2107 : Quoit Design
- 平面最近点对 ZOJ 2107 POJ 3714
- HDU 1007 ZOJ 2107 Quoit Design
- zoj 2107最短点对
- ACM-计算几何之Quoit Design——hdu1007 zoj2107
- zoj 2107 Quoit Design
- zoj 2107 Quoit Design(最近点对问题,好好思考,分治)
- ZOJ 2107
- ZOJ - 2107 Quoit Design [分治]
- HDU 1007:Quoit Design && ZOJ 2107:Quoit Design
- hdu 1007 && zoj 2107 Quoit Design [最近点对]