1_D closet pair最近邻点对

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">Description</span>

Given a set S = {p1, p2, ..., pn} of n points in the 1 dimensional space, find the two points of S whose distance is the smallest.

Input

There are multiple cases.

For each case, the first line is the number of points n (2<=n<=100000). The second line contains n real numbers.

Output

For each case, output the smallest distance, the answer is rounded to 6 digits after the decimal point.

题目解释:对于输入的一组数,每一数表示一个点的位置,求出最相近的邻点对

输入:第一行是点的个数n,第二行输入的是n个以空格分开的数

输出:求出最近邻点对的距离

解题思路:

使用分治的方法实现

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
typedef struct ClosetNode{    //用于存储一个区间内的最大值,最小值以及区间点的最近邻点对的距离
    double maxpos,minpos;
    double closet;
}CNode;

bool cmp(double a, double b){
    return a < b;
}
CNode Merge(CNode a, CNode b){        //子问题的合并
    CNode newNode;
    newNode.maxpos = a.maxpos > b.maxpos ? a.maxpos : b.maxpos;
    newNode.minpos = a.minpos < b.minpos ? a.minpos : b.minpos;
    newNode.closet = a.closet < b.closet ? a.closet :b.closet;
    newNode.closet = newNode.closet < (b.minpos - a.maxpos)? newNode.closet : (b.minpos - a.maxpos);
    return newNode;
}

CNode closet(vector<double> &data,int begin, int end){
    int mid = (begin + end)>>1;     // 进行问题分割
    int len = end - begin +1;
    if(len == 2){
        CNode a;
        a.maxpos = data[end];
        a.minpos = data[begin];
        a.closet = a.maxpos - a.minpos;
        return a;
    }
    if(len == 3){
        CNode b;
        b.maxpos = data[end] ;
        b.minpos = data[begin];
        b.closet = (b.maxpos - data[begin +1]) < (data[begin +1] - b.minpos) ? (b.maxpos - data[begin +1]):(data[begin +1] - b.minpos);
        return b;
    }
    CNode result;
    if(len >= 4){
        CNode left = closet(data,begin, mid);
        CNode right = closet(data,mid+1, end);
        result = Merge(left, right);
    }
    return result;
}
int main(){
    int n;
    while(cin >> n){
        if(n < 2 && n > 100000)break;
        int i;
        vector<double> data;
        for(i = 0; i < n; i++){
            double indata;
            cin >> indata;
            data.push_back(indata);
        }
        sort(data.begin(),data.end(),cmp);     //先使用排序处理区间
        CNode result = closet(data,0, n-1);
        cout <<  setprecision(6) << setiosflags(ios::fixed)<< result.closet << endl;
    }
    
    return 0;
}                                 


后记:

虽然老师说不要使用排序来对一组数进行处理,听了助教的思路是:对于每一个区间都分别求出最小值和最大值,但是觉得各个子问题区间还会有重叠,处理这个会稍微比较麻烦,暂时还没有实现不使用排序解决这个问题


代码新手,欢迎各位高手提出宝贵的意见和建议




你可能感兴趣的:(算法,sicily)