杭电 1007 最近点对,分治
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define N 100010
struct POINT
{
double x,y;
}point[N],ym[1000];
bool cmpx(POINT a,POINT b)
{
return a.x<b.x;
}
bool cmpy(POINT a,POINT b)
{
return a.y<b.y;
}
double distance1(POINT a,POINT b) //两点之间距离
{
return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
}
double min(double x,double y)
{
if(x<y) return x;
return y;
}
double closedistance(POINT * p,int left,int right)
{
int i,j,mid,yn;
double ans;
if(right==left+1)
return distance1(p[left],p[right]);
if(right==left+2)
return min( distance1(p[left],p[left+2]),min(distance1(p [left],p[left+1]),distance1(p[left+1],p[left+2])) );
mid=(left+right)>>1;
ans=min(closedistance(p,left,mid),closedistance(p,mid+1,right)); //找出两边的最小值, 与中间点对可能形成的最小值找出最小值
yn=0;
for( i=left;i<=right;i++)
if(p[i].x>=p[mid].x-ans && p[i].x<=p[mid].x+ans)
ym[yn++]=p[i];
std::sort(ym,ym+yn,cmpy);
for(i=0;i<yn;i++)
for( j=i+1;j<yn;j++)
{
if(ym[j].y-ym[i].y>=ans)
break;
ans=min(ans,distance1(ym[i],ym[j]));
}
return ans;
};
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
if(n<=0)break;
for( i=0;i<n;i++)
scanf("%lf%lf",&point[i].x,&point[i].y);
std::sort(point,point+n,cmpx);
printf("%.2lf\n",closedistance(point,0,n-1)/2);
}
return 0;
}
poj 3714
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define N 100010
struct POINT
{
double x,y;
int flag;
}point[N],ym[N];
bool cmpx(POINT a,POINT b)
{
return a.x<b.x;
}
bool cmpy(POINT a,POINT b)
{
return a.y<b.y;
}
double distance1(POINT a,POINT b)
{
if(a.flag!=b.flag)
return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
return 1e50;
}
double min(double x,double y)
{
if(x<y) return x;
return y;
}
double closedistance(POINT * p,int left,int right)
{
int i,j,mid,yn;
double ans;
if(right==left+1)
return distance1(p[left],p[right]);
if(right==left+2)
return min( distance1(p[left],p[left+2]),min(distance1(p[left],p[left+1]),distance1(p[left+1],p[left+2])) );
mid=(left+right)>>1;
ans=min(closedistance(p,left,mid),closedistance(p,mid+1,right));
yn=0;
for( i=left;i<=right;i++)
if(p[i].x>=p[mid].x-ans && p[i].x<=p[mid].x+ans)
ym[yn++]=p[i];
std::sort(ym,ym+yn,cmpy);
for(i=0;i<yn;i++)
for( j=i+1;j<yn;j++)
{
if(ym[j].y-ym[i].y>=ans)
break;
ans=min(ans,distance1(ym[i],ym[j]));
}
return ans;
};
int main()
{
int t,i,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lf%lf",&point[i].x,&point[i].y);
point[i].flag=0;
}
for(i=n;i<2*n;i++)
{
scanf("%lf%lf",&point[i].x,&point[i].y);
point[i].flag=1;
}
n<<=1;
std::sort(point,point+n,cmpx);
printf("%.3lf\n",closedistance(point,0,n-1));
}
return 0;
}