分治法-最近对问题

来源:互联网 发布:域名注册网络公司 编辑:程序博客网 时间:2024/05/01 02:51

问题描述:
输入:按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;}
1 0
原创粉丝点击