7-3 哪两个点之间的距离最近

7-3 哪两个点之间的距离最近[A]

P={(x1,y1),(x2,y2),⋯,(x**n,y**n)}是平面上散列的n个点的集合。请编写程序找出集合中距离最近的点对。严格地说,相同距离的最近点对可能不止一对,为了简单期间只找出第一对最近点对即可。

原题连接 PTA
参考文章算法分析与设计——最近点对问题

输入格式:

输入第一行给出一个正整数n,表示平面上的点数。随后n行,每行给出一个实数对,每个实数对表示一个点的纵横坐标值,其中第1数表示横坐标,第2数表示纵坐标。

输出格式:

输出最近点对中两个点的坐标和它们之间的距离。如果 x1+y1<=x2+y2则按
(x1,y1),(x2,y2),miniDist=Distance
输出结果,否则按
(x2,y2),(x1,y1),miniDist=Distance
输出结果。
  其中x1,y1,x2,y2是保留两位小数的实数,Distance是保留3位小数的实数

输入样例:

5

1.00 1.00

2.00 0.00

0.00 2.00

0.50 0.60

-1.00 2.00

输出样例:

(0.50,0.60),(1.00,1.00),miniDist=0.640


#include<iostream>
#include<cmath>
using namespace std;
class Point
{
    public:
        double x;
        double y;
        Point(double x, double y)
        {
            this->x = x;
            this->y = y;
        }
        Point()
        {
            this->x = 0;
            this->y = 0;
        }
        void print()
        {
            printf("(%.2f,%.2f),",this->x,this->y);
        }
        void set()
        {
            scanf("%lf %lf",&this->x, &this->y);
        }

};
void QuickSort(Point *arr, int low, int high)
{
    if (low < high)
    {
        int i = low, j = high;
        Point k = arr[low];
        while (i < j)
        {
            while(i < j && arr[j].x >= k.x)
            {
                j--;
            }
            if(i < j)
            {
                arr[i++] = arr[j];
            }
            while(i < j && arr[i].x < k.x)
            {
                i++;
            }
            if(i < j)
            {
                arr[j--] = arr[i];
            }
        }
        arr[i] = k;
        QuickSort(arr, low, i - 1);
        QuickSort(arr, i + 1, high);
    }
}
double Distance(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double minDistance(Point p[], int low, int high, Point ret[])
{
    double d1,d2,d3,delta;
    int ma = 0;
    Point mp[high-low+1],temp1[2],temp2[2],temp3[2];   
    if(high - low == 1)//只有两个点的情况,两点以及两点距离为答案
    {
        ret[0] = p[0];
        ret[1] = p[1];
        return Distance(ret[0],ret[1]);
    }
    else if(high - low == 2)//有三个点的情况
    {
        d1=Distance(p[low],p[low+1]);
        d2=Distance(p[low+1],p[high]);
        d3=Distance(p[low],p[high]);
        if((d1 < d2) && (d1 < d3))
        {
            ret[0] = p[low];
            ret[1] = p[low+1];
            return d1;
        }
        else if(d2<d3)
        {
            ret[0] = p[low+1];
            ret[1] = p[high];
            return d2;
        }
        else {
            ret[0] = p[low];
            ret[1] = p[high];
            return d3;
        }
    }
    else//大于三个点递归解决
    {
        int mid=(low+high)/2;//中位数大概位置
        d1 = minDistance(p,low,mid,ret);//左半平面
        temp1[0] = ret[0];
        temp1[1] = ret[1];
        d2 = minDistance(p,mid+1,high,ret);//右半平面
        temp2[0] = ret[0];
        temp2[1] = ret[1];
        if(d1 < d2)//给delta赋值为左右平面最小的值
        {
            delta = d1;
            ret[0] = temp1[0];
            ret[1] = temp1[1];
        }
        else 
        {
            delta = d2;
            ret[0] = temp2[0];
            ret[1] = temp2[1];
        }
        //把符合条件的点放入mp数组
        for(int i = mid; (i >= low) && (fabs(p[mid].x - p[i].x) < delta) && (fabs(p[mid].y - p[i].y < delta)); i--)
        {
            mp[ma++] = p[i];
        }
        for(int i = mid + 1; (i <= high) && (fabs(p[mid].x - p[i].x) < delta) && (fabs(p[mid].y - p[i].y < delta)); i++)
        {
            mp[ma++] = p[i];
        }
        QuickSort(mp, 0, ma - 1);
        for(int i = 0 ; i < ma ; i++)
        {
            for(int j = i + 1 ; j < ma ; j++)
            {
                d3 = Distance(mp[i],mp[j]);
                if(d3 < delta)
                {
                    ret[0] = mp[i];
                    ret[1] = mp[j];
                    delta = d3;
                }
            }
        }
        return delta;
    }
}
int main()
{
    Point p[100010], ans[2];
    double dis = 0.0;
    int n;
    scanf("%d",&n);
    for(int i = 0 ; i < n ; i++)
    {
        p[i].set();
    }
    QuickSort(p, 0, n-1);
    dis = minDistance(p, 0, n-1, ans);
    if(ans[0].x + ans[0].y <= ans[1].x + ans[1].y)
    {
        ans[0].print();ans[1].print();
    }
    else
    {
        ans[1].print();ans[0].print();
    }
    printf("miniDist=%.3f",dis);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值