红蓝最近点对

 

  1 #include <iostream>
  2 #include <ctime>
  3 #include <iterator>
  4 #include <functional>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <vector>
  8 using namespace std;
  9 struct Point
 10 {
 11     bool flag;
 12     double x;
 13     double y;
 14     Point(){}
 15     Point(double m_x, double m_y)
 16         :x(m_x), y(m_y){}
 17 }point [200005];
 18 int n;
 19 /************************************************************************/
 20 /* 函数功能:按点的X坐标排序                                            */
 21 /************************************************************************/
 22 struct CmpX : public binary_function<bool, Point, Point>
 23 {
 24     bool operator() (const Point& lhs, const Point& rhs)
 25     {
 26         return (lhs.x < rhs.x);
 27     }
 28 };
 29 /************************************************************************/
 30 /* 函数功能:按点的Y坐标排序                                            */
 31 /************************************************************************/
 32 struct CmpY : public binary_function<bool, Point, Point>
 33 {
 34     bool operator() (const Point& lhs, const Point& rhs)
 35     {
 36         return (lhs.y < rhs.y);
 37     }
 38 };
 39 /************************************************************************/
 40 /* 函数功能:求两点间的距离                                             */
 41 /************************************************************************/
 42 inline double Distance(const Point& lhs, const Point& rhs)
 43 {
 44     if(lhs.flag==rhs.flag)return 1e20;
 45     double x_diff = lhs.x - rhs.x;
 46     double y_diff = lhs.y - rhs.y;
 47     double res = x_diff * x_diff + y_diff *y_diff;
 48     return sqrt(res);
 49 }
 50 /************************************************************************/
 51 /* 函数功能:求数组中两点间的最短距离                                   */
 52 /************************************************************************/
 53 double GetShortestDistace(Point arr[], int low, int high)
 54 {
 55     double result = 0.;
 56 
 57     if (high - low < 3) //小于等于3个点时
 58     {
 59         if (high - low == 1) //2个点时
 60         {
 61             double distance = Distance(arr[low], arr[high]);
 62             return distance;
 63         }
 64         else //3个点
 65         {
 66             double distance1 = Distance(arr[low], arr[low + 1]);
 67             double distance2 = Distance(arr[low], arr[low + 2]);
 68             double distance3 = Distance(arr[low + 1], arr[low + 2]);
 69             return min(min(distance1, distance2), distance3);
 70         }
 71     }
 72     int middle = (low + high) / 2;
 73     double left_distance = GetShortestDistace(arr, low, middle);        //求middle左边的最短距离
 74     double right_distance = GetShortestDistace(arr, middle + 1, high);    //求middle右边的最短距离
 75 
 76     double delta = min(left_distance, right_distance); //中间区域的界限
 77     result = delta;
 78     vector<Point> midArea;    //存放中间条带区域的点
 79     for (int k = low; k < high; k++)
 80     {
 81         if(arr[k].x > arr[middle].x - delta && arr[k].x < arr[middle].x + delta)
 82             midArea.push_back(arr[k]);
 83     }
 84     sort(midArea.begin(), midArea.end(), CmpY()); //按Y坐标排序
 85     int size = midArea.size();
 86     for (int i = 0; i < size; i++)
 87     {
 88         int k = (i + 7) > size ? size : (i+7);    //只有选取出7个点(证明过程没看懂)
 89         for (int j = i+1; j < k; j++)
 90         {
 91             if(Distance(midArea.at(i), midArea.at(j)) < result)
 92                 result = Distance(midArea.at(i), midArea.at(j));
 93         }
 94     }
 95     return result;
 96 }
 97 
 98 int main()
 99 {
100     scanf("%d",&n);
101     for(int i=1;i<=n;i++)
102         scanf("%lf%lf",&point[i].x,&point[i].y),point[i].flag=0;
103     for(int i=1+n;i<=2*n;i++)
104         scanf("%lf%lf",&point[i].x,&point[i].y),point[i].flag=1;
105     n=n*2;
106     sort(point+1, point+ n+1, CmpX());
107     double res = GetShortestDistace(point, 1, n);
108     printf("%.3lf\n",res);
109 }

 

posted @ 2017-10-15 19:59  weeping  阅读(261)  评论(0编辑  收藏  举报