2750801 | 2008-02-14 13:48:15 | Accepted | 2107 | C++ | 00:02.95 | 4068K | C.D. |
分治算法的应用。在求左和右之间的最短点对时,先把满足X坐标差值小于CurMin的点对按Y排序,然后可以剪掉Y坐标值差小于CurMin的点对。
/**//*
作者 Crux.D
日期 2008.2.14
描述 分治求最短距离点对
*/
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
typedef struct
{
double x, y;
} Point;
Point p[100001];
int N, q[100000];
int init ();
double b_search ( int, int );
inline double dist ( int i, int j )
{
double x = sqrt ( ( p[i].x - p[j].x ) * ( p[i].x - p[j].x ) +
( p[i].y - p[j].y ) * ( p[i].y - p[j].y ) );
return x;
}
inline double min ( double a, double b )
{
return a > b ? b : a;
}
int cmpx ( const void *a, const void *b )
{
Point *A = ( Point * ) a, *B = ( Point * ) b;
return A->x > B->x;
}
int cmpq ( const void *a, const void *b )
{
int *A = ( int * ) a, *B = ( int * ) b;
return p[*A].y > p[*B].y;
}
int main ()
{
//freopen ( "in.txt", "r", stdin );
while ( init () )
{
printf ( "%0.2f\n", b_search ( 0, N - 1 ) / 2 );
}
return 0;
}
int init ()
{
scanf ( "%d", &N );
int i;
for ( i = 0; i < N; i ++ )
{
scanf ( "%lf%lf", &p[i].x, &p[i].y );
}
qsort ( p, N, sizeof ( p[0] ), cmpx );
return N;
}
double b_search ( int l, int r )
{
if ( l == r - 1 )
{
return dist ( l, r );
}
else if ( l == r - 2 )
{
return min ( dist ( r, l + 1 ), min ( dist ( l, r ), dist ( l, l + 1 ) ) );
}
else
{
int mid = ( l + r ) / 2;
double cur_min = min ( b_search ( l, mid ), b_search ( mid + 1, r ) );
int size = 0;
int i;
for ( i = mid - 1; i >= l && p[mid + 1].x - p[i].x < cur_min; i -- )
{
q[size ++] = i;
}
for ( i = mid + 1; i <= r && p[i].x - p[mid].x < cur_min; i ++ )
{
q[size ++] = i;
}
qsort ( q, size, sizeof ( q[0] ), cmpq );
int j;
for ( i = 0; i < size - 1; i ++ )
{
for ( j = i + 1; j < size && p[q[j]].y - p[q[i]].y < cur_min; j ++ )
{
cur_min = min ( cur_min, dist ( q[i], q[j] ) );
}
}
return cur_min;
}
}
作者 Crux.D
日期 2008.2.14
描述 分治求最短距离点对
*/
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
typedef struct
{
double x, y;
} Point;
Point p[100001];
int N, q[100000];
int init ();
double b_search ( int, int );
inline double dist ( int i, int j )
{
double x = sqrt ( ( p[i].x - p[j].x ) * ( p[i].x - p[j].x ) +
( p[i].y - p[j].y ) * ( p[i].y - p[j].y ) );
return x;
}
inline double min ( double a, double b )
{
return a > b ? b : a;
}
int cmpx ( const void *a, const void *b )
{
Point *A = ( Point * ) a, *B = ( Point * ) b;
return A->x > B->x;
}
int cmpq ( const void *a, const void *b )
{
int *A = ( int * ) a, *B = ( int * ) b;
return p[*A].y > p[*B].y;
}
int main ()
{
//freopen ( "in.txt", "r", stdin );
while ( init () )
{
printf ( "%0.2f\n", b_search ( 0, N - 1 ) / 2 );
}
return 0;
}
int init ()
{
scanf ( "%d", &N );
int i;
for ( i = 0; i < N; i ++ )
{
scanf ( "%lf%lf", &p[i].x, &p[i].y );
}
qsort ( p, N, sizeof ( p[0] ), cmpx );
return N;
}
double b_search ( int l, int r )
{
if ( l == r - 1 )
{
return dist ( l, r );
}
else if ( l == r - 2 )
{
return min ( dist ( r, l + 1 ), min ( dist ( l, r ), dist ( l, l + 1 ) ) );
}
else
{
int mid = ( l + r ) / 2;
double cur_min = min ( b_search ( l, mid ), b_search ( mid + 1, r ) );
int size = 0;
int i;
for ( i = mid - 1; i >= l && p[mid + 1].x - p[i].x < cur_min; i -- )
{
q[size ++] = i;
}
for ( i = mid + 1; i <= r && p[i].x - p[mid].x < cur_min; i ++ )
{
q[size ++] = i;
}
qsort ( q, size, sizeof ( q[0] ), cmpq );
int j;
for ( i = 0; i < size - 1; i ++ )
{
for ( j = i + 1; j < size && p[q[j]].y - p[q[i]].y < cur_min; j ++ )
{
cur_min = min ( cur_min, dist ( q[i], q[j] ) );
}
}
return cur_min;
}
}
评论