计算几何——平面最接近点对

 计算几何使人秃头,求平面最接近点对即在一个平面中有 n n n 个点,求这 n n n 点的最接近的两个点之间的距离,在洛谷上看,有大佬说旋转加排序(然鹅为啥要选择),个人觉得这个做法是不正确的,很容易被一些数据卡住。

正解的话应该是分治求解,首先将平面上点按照 x x x 轴分成左右均分的两部分 s 1 , s 2 s_1,s_2 s1,s2,那么对于最近的距离只有两种可能,

1. 1. 1. 两个点都在一个区域内, s 1 s_1 s1或者 s 2 s_2 s2

2. 2. 2. 两个点一个在 s 1 s_1 s1中,一个在 s 2 s_2 s2中。

基于上面的过程我们可以对其进行分治求解,知道出现区域内只剩下一个点和两个点的情况

1. 1. 1. 只剩一个点,返回 I N F INF INF

2. 2. 2. 只剩两个点,返回这两个点之间的距离

t h e   c o d e the\space code the code

#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 1000001;
const int INF = 2 << 20;
int n, temp[maxn];
struct Point
{
    double x, y;
} S[maxn];
bool cmp(const Point &a, const Point &b)
{
    if(a.x == b.x) return a.y < b.y;
    else return a.x < b.x;
}
bool cmps(const int &a, const int &b) { return S[a].y < S[b].y; }
double min(double a, double b) { return a < b ? a : b; }
double dist(int i, int j)
{
    double x = (S[i].x - S[j].x) * (S[i].x - S[j].x);
    double y = (S[i].y - S[j].y) * (S[i].y - S[j].y);
    return sqrt(x + y);
}
double merge(int left, int right)
{
    double d = INF;
    if(left == right) return d;
    if(left + 1 == right) return dist(left, right);
    int mid = (left + right ) >> 1;
    double d1 = merge(left, mid);
    double d2 = merge(mid + 1, right);
    d = min(d1, d2);
    int i, j, k = 0;
    for(i = left; i <= right; i++)
        if(fabs(S[mid].x - S[i].x) < d) // 这里不太一样
            temp[k++] = i;
    sort(temp, temp + k, cmps);
    for(i = 0; i < k; i++)
        for(j = i + 1; j < k && S[temp[j]].y - S[temp[i]].y < d; j++)
        {
            double d3 = dist(temp[i], temp[j]);
            if(d > d3) d = d3;
        }
    return d;
}
int main()
{
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%lf%lf", &S[i].x, &S[i].y);
    sort(S, S + n, cmp);
    return !printf("%.4lf\n", merge(0, n - 1));
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值