分割統治法 - 最小距離の最も近い点を-hdu 1007輪投げデザイン

 

 

それぞれ境界として左右二つの部分、最も近いポイントのシーク距離の左右の部分に中間座標、及び次いで合わせ、x座標でソートn個の点、パーティションの使用を考えました。二つの部分の最も近い距離dについて決定され、統合プロセスは、ストリップ幅部2dは二組に属する2つの点があり、距離がdよりも小さい、最大n個の点が存在してもよいかどうかを確認する必要があり、最悪の場合の時間がマージO(N ^ 2)である。しかし、疎な性質を持つ点の左右には、左右の任意の点について、点の右側は、矩形のD * 2dと、検査及びせいぜい6内に入らなければならない下点(鳩の巣原理)yの並び順第一帯状部点座標ように、線形スキャンので、O(nlogn)の合成時の複雑。

#include <bits/stdc++.h>

using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
int n;
struct Point
{
    double x,y;
} a[N],b[N];

bool cmpx(const Point a,const Point b)
{
    return a.x<b.x;
}

bool cmpy(const Point a,const Point b)
{
    return a.y<b.y;
}

double dis(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}


double solve(int l,int r)
{
    if (l==r)
    {
        return inf;
    }
    int mid=(l+r)>>1,tail=0;
    double d=min(solve(l,mid),solve(mid+1,r));
    for (int i=mid; i>=l&&a[mid].x-a[i].x<d; i--)
    {
        b[tail++]=a[i];
    }
    for (int i=mid+1; i<=r&&a[i].x-a[mid].x<d; i++)
    {
        b[tail++]=a[i];
    }
    sort(b,b+tail,cmpy);
    for (int i=0; i<tail; i++)
    {
        for (int j=i+1; j<tail&&b[j].y-b[i].y<d; j++)
        {
            d=min(d,dis(b[i],b[j]));
        }
    }
    return d;
}



int main()
{
    while (scanf("%d",&n))
    {
        if (!n)
        {
            break;
        }
        for (int i=1; i<=n; i++)
        {
            scanf("%lf%lf",&a[i].x,&a[i].y);
        }
        sort(a+1,a+n+1,cmpx);
        double ans=solve(1,n)/2;
        printf("%.2lf\n",ans);
    }
}

  

おすすめ

転載: www.cnblogs.com/Accpted/p/11262728.html
おすすめ