分治法-最近對問題
阿新 • • 發佈:2019-01-10
問題描述:
輸入:按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;
}