【数据结构二模自救篇】【分治】平面上的最接近点对

题目描述:
给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的。

输入:
第一行:n;2≤n≤60000
接下来n行:每行两个实数:x y,表示一个点的行坐标和列坐标,中间用一个空格隔开。

输出:
仅一行,一个实数,表示最短距离,精确到小数点后面4位。

样例输入:
3
1 1
1 2
2 2

样例输出:
1.0000

蛮力法参考代码:

#include <stdio.h>
#include <math.h>

#define INF 0x3f3f3f3f

int n;
double x[60001];
double y[60001];

double cp()
{
    
    
	int i,j;
	double dist,mindist=INF; 
	for(i=0;i<n;i++)
	{
    
    
		for(j=i+1;j<n;j++)
		 {
    
    
		 	dist=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
		 	if(dist<mindist)
             mindist=dist;
		 }  
	}
	
	return mindist;
} 

int main()
{
    
    
	scanf("%d",&n);
	
	int i;
	for(i=0;i<n;i++)
	 scanf("%lf%lf",&x[i],&y[i]);
	
	printf("%.4lf",sqrt(cp()));
	return 0;
}

分治法参考代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int n;

struct point{
    
    
	double x,y;
};

struct point p[60001];

int cmp1(const void *a,const void *b)
{
    
    
	struct point* pa=(struct point*)a;
	struct point* pb=(struct point*)b;
	double num1=pa->y;
	double num2=pb->y;
	if(num1-num2>0)
	 return 1;
	else
	 return -1;
}

int cmp2(const void *a,const void *b)
{
    
    
	struct point* pa=(struct point*)a;
	struct point* pb=(struct point*)b;
	double num1=pa->x;
	double num2=pb->x;
	if(num1-num2>0)
	 return 1;
	else
	 return -1; 
}

double distance(struct point a,struct point b)
{
    
    
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double cp(int low,int high)
{
    
    
	double d1,d2,d3,d;
	int mid,i,j,index=0;
	struct point s[high-low+1];
	
	if(high-low==1)
	  return distance(p[low],p[high]);

	if(high-low==2)
    {
    
    
    	d1=distance(p[low],p[low+1]);
    	d2=distance(p[low+1],p[high]);
    	d3=distance(p[low],p[high]);
    	if((d1<d2)&&(d1<d3))
    	 return d1;
    	else if(d2<d3)
    	 return d2;
    	else
    	 return d3;
	}
	
	mid=(low+high)/2;
	d1=cp(low,mid);
	d2=cp(mid+1,high);
	d=(d1<d2?d1:d2);
	
	for(i=mid;i>=low&&p[mid].x-p[i].x<d;i--)
	 s[index++]=p[i];
	for(i=mid+1;i<=high&&p[i].x-p[mid].x<d;i++)
	 s[index++]=p[i];
	
	qsort(s,index,sizeof(struct point),cmp1);
	
	for(i=0;i<index;i++)
	{
    
    
		for(j=i+1;j<index&&j<=i+7;j++)
		{
    
    
			if(s[j].y-s[i].y>=d)
			 break;
			else
			 d3=distance(s[i],s[j]);
			 if(d3<d)
			  d=d3;
		}
	}
   return d;
}

int main()
{
    
    
	scanf("%d",&n);
	int i;
	
	for(i=0;i<n;i++)
	 scanf("%lf%lf",&p[i].x,&p[i].y);
	
	qsort(p,n,sizeof(struct point),cmp2);
	
	printf("%.4lf",cp(0,n-1));
	return 0;
}

参考资料:
https://blog.csdn.net/qq_28666193/article/details/53351482?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&dist_request_id=6353288c-1162-41cc-a4ec-0637ce887505&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control

猜你喜欢

转载自blog.csdn.net/qq_46139801/article/details/114161936