<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; }
虽然老师说不要使用排序来对一组数进行处理,听了助教的思路是:对于每一个区间都分别求出最小值和最大值,但是觉得各个子问题区间还会有重叠,处理这个会稍微比较麻烦,暂时还没有实现不使用排序解决这个问题
代码新手,欢迎各位高手提出宝贵的意见和建议