讲解网上都有。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 100002
struct ss
{
double x;
double y;
};
ss px[maxn],py[maxn];
bool cmpx(ss p1,ss p2)
{
return p1.x<p2.x;
}
bool cmpy(ss p1,ss p2)
{
return p1.y<p2.y;
}
double get_dis(ss p1,ss p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double mindis(double a,double b)
{
return a>b?b:a;
}
double closest(int s,int e)
{
if(e-s==1)
return get_dis(px[s],px[e]);
if(e-s==2)
return mindis(get_dis(px[s],px[s+1]),mindis(get_dis(px[s],px[e]),get_dis(px[s+1],px[e])));
int mid=(s+e)>>1;
double ans=mindis(closest(s,mid),closest(mid+1,e));
int i,j,cnt=0;
for(i=s;i<=e;i++)
if(px[i].x>=px[mid].x-ans&&px[i].x<=px[mid].x+ans)
py[cnt++]=px[i];
std::sort(py,py+cnt,cmpy);
for(i=0;i<cnt;i++)
for(j=i+1;j<cnt;j++)
{
if(py[j].y-py[i].y>=ans)
break;
ans=mindis(ans,get_dis(py[i],py[j]));
}
return ans;
}
int main()
{
//freopen("Input.txt","r",stdin);
int n,i;
while(scanf("%d",&n)&&n)
{
for(i=0;i<n;i++)
scanf("%lf%lf",&px[i].x,&px[i].y);
std::sort(px,px+n,cmpx);
double dis=closest(0,n-1);
printf("%.2lf\n",dis/2);
}
return 0;
}
poj 3714
多加了已给判断,并且是另一种求最小点对的方法。当成模板用。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const double inf=1e9;
struct node
{
double x,y;
int id;
}point[200005];
int n;
bool cmp(node p1,node p2)
{
if(p1.x != p2.x) return p1.x < p2.x;
else return p1.y < p2.y;
}
double dist(node a, node b)
{
if(a.id==b.id) return inf;
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
double getmin(double a, double b)
{
return a<b?a:b;
}
double Get_Small_Dis(int l,int r)
{
if(l == r)
return inf;
if(l == r - 1) //两个点
return dist(point[l],point[r]);
if(l == r - 2)
return getmin(getmin(dist(point[l],point[l+1]),dist(point[l+1],point[l+2])),dist(point[l],point[l+2]));
int i,j,mid = (l+r) >> 1;
double res = getmin(Get_Small_Dis(l,mid),Get_Small_Dis(mid+1,r));
for(i=l;i<=r;i++)
{
for(j=i+1;j<=i+5 && j<=r;j++)
{
res = getmin(res,dist(point[i],point[j]));
}
}
return res;
}
void init(double &res) //输入函数,节约时间,poj上排名靠前,运行时间不超过300ms,个人猜也是用输入外挂了吧。
{
char ch;
int flag=0,tmp=0,n,m,num=0;
while((ch=getchar())<'0'||ch>'9')
if(ch=='-') flag=1;
for(m=0,n=0; (ch>='0'&&ch<='9')|| (ch=='.');ch=getchar())
{
if(ch=='.') { tmp=1;continue;}
if(!tmp) m=m*10+ch-'0';
if(tmp) { n=n*10+ch-'0'; num++;}
}
res=m+n*1.0/pow(10,num);
if(flag) res*=-1;
}
int main()
{
//freopen("Input.txt","r",stdin);
int i,ncase;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
init(point[i].x);
init(point[i].y);
point[i].id=0;
}
n<<=1;
for(;i<n;i++)
{
init(point[i].x);
init(point[i].y);
point[i].id=1;
}
sort(point,point+n,cmp);
double ans = Get_Small_Dis(0,n-1);
printf("%.3f\n",ans);
}
return 0;
}