您的位置:首页 > 其它

hdoj 1007 临近点对算法模板

2016-07-18 23:04 381 查看
思想 分治

所有点按x坐标排序

每次把整体分成两边求出两边所有点中的最短距离然后求出中间一下片点的最短距离最后合并得总体最短距离

#include<cstdio>
#include<vector>
#include<algorithm>
#include<iostream>
#include<cmath>
#define LL long long
#define pi acos(-1.0)
#define maxn 100005
using namespace std;
struct node{
double x,y;
}no[maxn],no2[maxn];
int n;
double min(double a,double b)
{
return a<b?a:b;
}
bool cmpX(node a,node b)
{
return a.x<b.x;
}
bool cmpY(node a,node b)
{
return a.y<b.y;
}
double dis(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double closet(int s,int e)
{
if(e-s==1) return dis(no[s],no[e]);
if(e-s==2) return min(min(dis(no[s],no[s+1]),dis(no[s+1],no[e])),dis(no[s],no[e]));
int mid = (s+e)>>1;
double ans = min(closet(s,mid),closet(mid+1,e));

int l = 0; //合并
for(int i=s;i<=e;i++) if(no[i].x>no[mid].x-ans&&no[i].x<no[mid].x+ans)no2[l++] = no[i];
sort(no2,no2+l,cmpY);
for(int i=0;i<l;i++)
for(int j=i+1;j<l;j++)
{
if(no2[j].y-no2[i].y>=ans)break;
ans = min(ans,dis(no2[i],no2[j]));
}
return ans;
}
int main()
{
while(scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)scanf("%lf %lf",&no[i].x,&no[i].y);
sort(no,no+n,cmpX);
printf("%.2f\n",closet(0,n-1)/2.0);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: