红蓝最近点对
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 }
作者:weeping
出处:www.cnblogs.com/weeping/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。