[Swust OJ 794]--最近对问题(分治)

 

题目链接:http://acm.swust.edu.cn/problem/794/

 

Time limit(ms): 1000      Memory limit(kb): 10000
 
Description
设p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n个点构成的集合S,设计算法找出集合S中距离最近的点对。
 
Input

多组测试数据,第一行为测试数据组数n(0<n≤100),每组测试数据由两个部分构成,第一部分为一个点的个数m(0<m≤1000),紧接着是m行,每行为一个点的坐标x和y,用空格隔开,(0<x,y≤100000)

 
Output

每组测试数据输出一行,为该组数据最近点的距离,保留4为小数。

 
Sample Input
2
2
0 0
0 1
3
0 0
1 1
1 0
 

Sample Output
1.0000
1.0000
Hint
algorithm textbook
 
不想多说,前几天写了一篇博客,主要讲的就是平面最近点对的问题,可以戳戳这里:http://www.cnblogs.com/zyxStar/p/4591897.html
直接上代码:
 1 #include <iostream>  

 2 #include <cstdio>  

 3 #include <cstring>  

 4 #include <cmath>  

 5 #include <algorithm>  

 6 using namespace std;

 7 const double inf = 1e20;

 8 const int maxn = 100005;

 9 

10 struct Point{

11     double x, y;

12 }point[maxn];

13 

14 int n, mpt[maxn], t;

15 

16 //以x为基准排序

17 bool cmpxy(const Point& a, const Point& b){

18     if (a.x != b.x)

19         return a.x < b.x;

20     return a.y < b.y;

21 }

22 

23 bool cmpy(const int& a, const int& b){

24     return point[a].y < point[b].y;

25 }

26 

27 double min(double a, double b){

28     return a < b ? a : b;

29 }

30 

31 double dis(int i, int j){

32     return sqrt((point[i].x - point[j].x)*(point[i].x - point[j].x) + (point[i].y - point[j].y)*(point[i].y - point[j].y));

33 }

34 

35 double Closest_Pair(int left, int right){

36     double d = inf;

37     if (left == right)

38         return d;

39     if (left + 1 == right)

40         return dis(left, right);

41     int mid = (left + right) >> 1;

42     double d1 = Closest_Pair(left, mid);

43     double d2 = Closest_Pair(mid + 1, right);

44     d = min(d1, d2);

45     int i, j, k = 0;

46     //分离出宽度为d的区间  

47     for (i = left; i <= right; i++){

48         if (fabs(point[mid].x - point[i].x) <= d)

49             mpt[k++] = i;

50     }

51     sort(mpt, mpt + k, cmpy);

52     //线性扫描  

53     for (i = 0; i < k; i++){

54         for (j = i + 1; j < k && point[mpt[j]].y - point[mpt[i]].y<d; j++){

55             double d3 = dis(mpt[i], mpt[j]);

56             if (d > d3)    d = d3;

57         }

58     }

59     return d;

60 }

61 

62 int main(){

63     scanf("%d", &t);

64     while (t--){

65         scanf("%d", &n);

66         for (int i = 0; i < n; i++)

67             scanf("%lf %lf", &point[i].x, &point[i].y);

68         sort(point, point + n, cmpxy);

69         printf("%.4lf\n", Closest_Pair(0, n - 1));

70     }

71     return 0;

72 }
View Code

 

你可能感兴趣的:(问题)