设P={(x 1 ,y 1 ),(x 2 ,y 2 ),⋯,(x n ,y n )}是平面上散列的n个点的集合。请编写程序找出集合中距离最近的点对。严格地说,相同距离的最近点对可能不止一对,为了简单期间只找出第一对最近点对即可。
输入格式:
输入第一行给出一个正整数n,表示平面上的点数。随后n行,每行给出一个实数对,每个实数对表示一个点的纵横坐标值,其中第1数表示横坐标,第2数表示纵坐标。
输出格式:
输出最近点对中两个点的坐标和它们之间的距离。如果 x1+y1<=x2+y2则按
(x1,y1),(x2,y2),miniDist=Distance
输出结果,否则按
(x2,y2),(x1,y1),miniDist=Distance
输出结果。
其中x1,y1,x2,y2是保留两位小数的实数,Distance是保留3位小数的实数
输入样例:
5
1.00 1.00
2.00 0.00
0.00 2.00
0.50 0.60
-1.00 2.00
输出样例:
(0.50,0.60),(1.00,1.00),miniDist=0.640
问题分析
好像可以用分治法???不会做找了很久都没找到,就简单粗暴的穷举法吧,
把它的所有点对的距离都算出来,找出最小的距离,记录它的下标。
常用的无穷大常量——0x3f3f3f3f
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n;
cin>>n;
double x[n],y[n];
for(int i=0; i<n; i++)
{
cin>>x[i]>>y[i];
}
int dx,dy;
int i,j;
double nmin=0x3f3f3f3f;
for(i = 0; i< n ; i ++)
{
for(j = i + 1; j < n ; j ++)
{
double sum=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
if(sum<nmin)
{
nmin=sum;
dx=i;
dy=j;
}
}
}
if((x[dx]+y[dx])<=x[dy]+y[dy])
{
printf("(%.2lf,%.2lf),(%.2lf,%.2lf),miniDist=%.3lf",x[dx],y[dx],x[dy],y[dy],nmin);
}
else
printf("(%.2lf,%.2lf),(%.2lf,%.2lf),miniDist=%.3lf",x[dy],y[dy],x[dx],y[dx],nmin);
}