您的位置:首页 > 大数据 > 人工智能

UVA 10245 - The Closest Pair Problem

2014-10-15 21:35 344 查看
这题采用分割法,利用hash和二分的思想可以写出高效算法。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

const int size_n = 10000 + 100;

double a[size_n][2];
int cur;
const int h_size = 100001;
int h[size_n * 10];
int s[size_n][2];
unsigned long long s2[size_n];

double ebsp = 1e-4;

int f(double x , int n)
{
cur = 1;
memset(h , 0 , sizeof(h));
double t = sqrt(0.5) * x;
int len = (int)(40001.1 / t) + 1;
for(int i = 0 ; i < n ; ++i)
{
int tx = (int)(a[i][0] / t);
int ty = (int)(a[i][1] / t);

unsigned long long total = (unsigned long long)tx * len + ty;
int index = (total) % h_size;
s2[cur] = total;
s[cur][1] = h[index];
s[cur][0] = i;
h[index] = cur;

unsigned long long des = s2[cur];
for(int k = s[cur++][1] ; k ; k = s[k][1])
{
if((s2[k] == des)) return 1;
}
}
return 0;
}

int d[][2] = {{-3 , -3} , {-3 , -2} , {-3 , -1} , {-3 , 0} , {-3 , 1} , {-3 , 2} , {-3 , 3} ,
{-2 , -3} , {-2 , -2} , {-2 , -1} , {-2 , 0} , {-2 , 1} , {-2 , 2} , {-2 , 3} ,
{-1 , -3} , {-1 , -2} , {-1 , -1} , {-1 , 0} , {-1 , 1} , {-1 , 2} , {-1 , 3} ,
{0 , -3} , {0 , -2} , {0 , -1}                  , {0 , 1} , {0 , 2} , {0 , 3} ,
{1 , -3} , {1 , -2} , {1 , -1} , {1 , 0} , {1 , 1} , {1 , 2} , {1 , 3} ,
{2 , -3} , {2 , -2} , {2 , -1} , {2 , 0} , {2 , 1} , {2 , 2} , {2 , 3} ,
{3 , -3} , {3 , -2} , {3 , -1} , {3 , 0} , {3 , 1} , {3 , 2} , {3 , 3}};

double g(double dis , int n)
{
double t = sqrt(0.5) * dis;
int  len = (int)(40001.1 / t) + 1;
double min_r = 10000;

for(int i = 0 ; i < n ; ++i)
{
int x = (int)(a[i][0] / t);
int y = (int)(a[i][1] / t);

for(int j = 0 ; j < 48 ; ++j)
{
int tx = x + d[j][0];
if(tx < 0 || tx >= len) continue;

int ty = y + d[j][1];
if(ty < 0 || tx >= len) continue;

unsigned long long total = (unsigned long long)tx * len +  ty;
int index = total % h_size;
int r = h[index];
for( ; r  ; r = s[r][1])
{
int tt = s[r][0];
if(tt == i) continue;
double tr = sqrt((a[i][0] - a[tt][0] ) * (a[i][0] - a[tt][0]) + (a[i][1] - a[tt][1]) * (a[i][1] - a[tt][1]));
if(min_r > tr) min_r = tr;
}
}
}
return min_r;
}

int main()
{
int n;
while(scanf("%d" , &n) == 1 && n)
{
for(int i = 0 ; i < n ; ++i)
scanf("%lf%lf" , a[i] , a[i] + 1);

int r;
double now = 20000;
do{
now /= 2;
r = f(now , n);
if(now < 1e-4) break;
}while(r);
double res;
if(now < 1e-4) res = 0;
else res = g(now , n);
if(res < 10000) printf("%.4f\n" , res);
else printf("INFINITY\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: