pku 3714(最近点对)

 1 /*

 2 *  题目要求:求最近点对(一个点在station内,一个点在agent内) 

 3 */

 4 

 5 #include <cmath>

 6 #include <cstdio>

 7 #include <cstdlib>

 8 #include <iostream>

 9 #include <algorithm>

10 

11 using namespace std;

12 

13 const int N = 200005;

14 const double INF = 1e20;

15 

16 struct point {

17     int f;

18     double x;

19     double y;

20 }p[N];

21 int tmp[N];

22 

23 double dis(point A, point B) {

24     return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));

25 }

26 

27 int cmp(const point &a, const point &b) {

28     if (a.x != b.x) return a.x < b.x;

29     return a.y < b.y;

30 }

31 

32 int cmp1(const int &a, const int &b) {

33     return p[a].y < p[b].y;

34 }

35 

36 double min(double a, double b) {

37     return a > b ? b : a;

38 }

39 

40 double closestPair(int left, int right) {

41     double d = INF;

42     if (left == right) return d;      //同属station点,返回无穷大 

43     if (left+1 == right) return d;    //同属agent点,返回无穷大

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

45     double d1 = closestPair(left, mid);

46     double d2 = closestPair(mid+1, right);

47     d = min(d1, d2);

48     int k = 0;

49     for (int i=left; i<=right; ++i) {

50         if (fabs(p[mid].x- p[i].x) <= d) tmp[k++] = i;

51     }

52     sort(tmp, tmp+k, cmp1);

53     for (int i=0; i<k; ++i) {//只有当一个点为station的点,另一个点为agent点时,才计算两点距离 

54         for (int j=i+1; j<k && p[tmp[j]].y-p[tmp[i]].y<d && ((p[tmp[j]].f==0&&p[tmp[i]].f==1)||(p[tmp[j]].f==1&&p[tmp[i]].f==0)); ++j) {

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

56             if (d3 < d) d = d3;

57         }

58     }

59     return d;

60 } 

61 

62 int main() {

63     int n, t;

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

65     while (t--) {

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

67         for (int i=0; i<n; ++i) {

68             scanf ("%lf%lf", &p[i].x, &p[i].y);

69             p[i].f = 0;  //标志为station的点 

70         }

71         for (int i=n; i<n+n; ++i) {

72             scanf ("%lf%lf", &p[i].x, &p[i].y);

73             p[i].f = 1;  //标志为agent的点 

74         }

75         if (n == 1) printf ("%.lf\n", dis(p[0], p[1]));//只有两个点,直接算 

76         else {

77             sort(p, p+n+n, cmp);

78             double ans = closestPair(0, n+n-1);

79             printf ("%.3lf\n", ans);

80         } 

81     }

82     return 0;

83 }

 

你可能感兴趣的:(pku)