poj 3714 Raid(平面最近点对)

题意:

   给定在同一平面中,同数量黑点与白点的坐标值,求其中最近黑白点对的距离。

—————————————————————————————————————————

大水题一遍过QAQ  稍微做点工作就是把同颜色的点,做上标记,同颜色的点就使其之间距离inf……

分治or暴力+剪枝都可以过。

————————————————————————————————————————————

#include<cmath>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=200009;
int n,T;
struct node
{
    bool flg;
    double x,y;
}a[maxn],q[maxn];

double absolute(double u)                         {return u>=0?u:-u;}
double min(double u,double v)                    {return u<v?u:v;}
inline bool make_x(const node &u,const node &v) {return u.x<v.x;}
inline bool make_y(const node &u,const node &v) {return u.y<v.y;}
//计算两点间的距离 
double length(const node &u,const node &v)
{
    if(u.flg==v.flg) return inf;
    return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y));
}
 
inline double solve(int u,int v)
{
    if(u==v) return inf;//只有一个点 
    int k=0,m=(u+v)/2;
    double ans=min(solve(u,m),solve(m+1,v));
    for(int i=u;i<=v;i++)
        if(absolute(a[i].x-a[m].x)<=ans)
            q[k++]=a[i];
            
    sort(q+1,q+k+1,make_y);//预排序 
    for(int i=1;i<=k;i++)
        for(int j=i+1;j<=k;j++)
        {
            if((q[j].y-q[i].y)>ans) break;
            ans=min(ans,length(q[j],q[i]));
        }
    return ans;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&a[i].x,&a[i].y);
            a[i].flg=0;//标记以便区分是否同集合 
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&a[i+n].x,&a[i+n].y);
            a[i+n].flg=1;
        }
        
        sort(a+1,a+2*n+1,make_x);
        printf("%.3lf\n",solve(1,2*n));
    }
    return 0;
}
View Code

 

posted @ 2017-06-10 20:08  BK-Edwina  阅读(411)  评论(0编辑  收藏  举报