您的位置:首页 > 大数据 > 人工智能

POJ 3714-Raid解题报告

2012-10-07 16:51 651 查看
二维最近点对问题,关于这个问题网上和算法导论上都由详细的介绍http://hi.baidu.com/bananas122/item/fbc7a2b6d766bf6e254b09e4

这个解释的挺好,并且还有计算,其他的就是代码实现的问题,另外这个题要加一个标志位,就没什么特殊的了

View Code

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define N 200005
#define min(a,b) ((a)<(b)?(a):(b))
#define inf 1e50
using namespace std;
struct point
{
double x,y;
int flag;
};
point p
;
point tmp1
;
point tmp2
;
bool cmp(point a,point b)
{
if(a.x!=b.x)
return a.x<b.x;
return a.y<b.y;
}
double dis(point p1,point p2)
{
if(p1.flag==p2.flag)
return inf;
return sqrt(((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
}
double mindis(int l,int r)
{
double d=inf;
if(l==r)
return d;
if(l+1==r)
return dis(p[l],p[r]);
int mid=(l+r)>>1;
double d1=mindis(l,mid);//分治,这里感觉有些像线段树
double d2=mindis(mid+1,r);
d=min(d1,d2);
int i,j,k;
int cnt1,cnt2;
cnt1=cnt2=0;
for(i=mid;i>=l;i--)//找两边的点
{
if(p[mid].x-p[i].x<d)
tmp1[cnt1++]=p[i];
}
for(i=mid+1;i<=r;i++)
{
if(p[i].x-p[mid].x<d)
tmp2[cnt2++]=p[i];
}
for(i=0;i<cnt1;i++)
for(j=0;j<cnt2;j++)
{
d1=dis(tmp1[i],tmp2[j]);
if(d1<d)
d=d1;
}
return d;
}
int main()
{
int n,i,j,k;
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
p[i].flag=0;
}
for(i=n;i<2*n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
p[i].flag=1;
}
n*=2;
sort(p,p+n,cmp);//一定要用sort
printf("%.3lf\n",mindis(0,n-1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: