hdoj1007

来源:互联网 发布:最便宜的淘宝网 编辑:程序博客网 时间:2024/06/05 20:38
HDOJ1007,求平面上一组坐标点中距离最近的两点间距离。参考此链接介绍的方法 HDU1007查找平面最近点对  。具体实现看代码及注解。
#include <iostream>#include <cmath>#include <algorithm>#include <iomanip>using namespace std;// 坐标点struct coordinate {double x;double y;};coordinate array[100005];// 坐标数组int tmp[100005];// 计算两点间距离inline double dist(coordinate a, coordinate b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}// 求最小值double min(double a, double b){return a < b ? a : b;}// 为sort函数提供排序依据,按x轴排序bool cmpx(coordinate a, coordinate b){return a.x < b.x;}// 为sort函数提供排序依据,按y轴排序double cmpy(int a, int b){return array[a].y < array[b].y;}// 核心算法,递归地求解最距离坐标点对// 参数 l r :沿x轴从小到大排序后,区域内左边和最右边的数组下标double find(int l , int r){//递归算法if (r == l+1) return dist(array[l], array[r]);if (l+2 == r)return min( dist(array[l],array[r]),min(dist(array[l+1], array[r]),dist(array[l],array[l+1])));int mid = (l+r)>>1;// mid_d 最小距离double min_d = min(find(l,mid),find(mid+1,r));// 递归算法结束,考虑特殊情况:最短距离的坐标点对分别在mid的左右两边int i, j, cnt = 0;for (i = l; i <= r; i++){// 沿x轴将[mid-min_d, mid+min_d]的所有点划入考虑范围,距离mid大于min_d的点说明不是最小距离// tmp数组沿x从小到大的顺序存放考虑范围内坐标点在array数组中的下标if (array[i].x >= array[mid].x - min_d && array[i].x <= array[mid].x + min_d)tmp[cnt++] = i;}// 对考虑范围内的点按y轴从小到大排序sort(tmp, tmp+cnt, cmpy);// 对考虑范围内的点两两计算距离,因为是按照y轴排序,若y轴方向上大于min_d,则不用再计算了for (i = 0; i < cnt; i++){for (j = i+1; j < cnt; j++){if (array[tmp[j]].y - array[tmp[i]].y >= min_d) break;min_d = min(min_d, dist(array[tmp[i]], array[tmp[j]]));}}return min_d;}// main函数int main(void){int n;while (cin >> n && n != 0) {for (int i = 0; i < n; i++){cin >> array[i].x >> array[i].y;}sort(array, array + n, cmpx);cout << fixed <<setprecision(2) <<find(0,n-1)/2 << endl;}return 0;}

0 0