1. 程式人生 > >分治法-最近對問題

分治法-最近對問題

問題描述:
輸入:按x座標升序排列的n(n>=2)個點的集合,S={(x1,y1),(x2,y2)….(xn,yn)}
輸出:最近點對的距離。
分析:
用m=(low+high)/2,講點劃分為兩部分,d1=左半部分點的最近距離,d2=右半部分點的最近對距離,d=min(d1,d2)。還需考慮在中線兩邊的點的最近距離,且只用考慮與中線距離

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

struct point
{
    int x,y;
};

int
cmp(point a ,point b) { return a.y<b.y; } double Disttance(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double Closest(point s[],int low,int high); int n; int main() { double MinD; point p[10010]; cin>>n; for(int i=0;i<n;i++) { cin
>>p[i].x>>p[i].y; } MinD = Closest(p,0,n-1); cout<<MinD<<endl; return 0; } double Closest(point s[],int low,int high) { double d1,d2,d3,d; int mid,i,j,index; point p[n]; if(high-low == 1) return Disttance(s[low],s[high]); if(high-low == 2
) { d1 = Disttance(s[low],s[low+1]); d2 = Disttance(s[low+1],s[high]); d3 = Disttance(s[low],s[high]); if(d1<d2 && d1<d3) return d1; else { if(d2<d3) return d2; else return d3; } } else { mid = (low+high)/2; d1 = Closest(s,low,mid); d2 = Closest(s,mid+1,high); if(d1<d2) d = d1; else d = d2; index = 0; for(i=mid;i>=low && s[i].x-s[mid].x<d;i--) p[index++] = s[i]; for(j=mid+1;j<=high && s[j].x-s[mid].x<d;j++) p[index++] = s[j]; sort(p,p+index,cmp); for(i=0;i<index;i++) { for(j=i+1;j<index;j++) { if(p[j].y-p[i].y>=d) break; else { d3 = Disttance(p[j],p[i]); if(d3<d) d = d3; } } } } return d; }