#include<iostream>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<utility>
#include<climits>
#define endl "\n"
#define inf INT_MAX
using namespace std;
struct point{
int x,y;
}s[101];
bool compx(point a,point b){
return a.x<b.x;
}
bool compy(point a,point b){
return a.y>b.y;
}
double Distance(point a,point b){
double dx=a.x-b.x;
double dy=a.y-b.y;
double dis=sqrt(dx*dx+dy*dy);
return dis;
}
pair<point,point> Closest(point S[],int low,int high){
double d1,d2,d3,d;
pair<point,point> o1,o2,o3,o;
int min,i,j,index;
point P[101]; //存放点集合P1和P2
if(high-low==1){ //只有两个点,返回两点之间的距离
o.first=S[low];
o.second=S[high];
return o;
}
if(high-low==2){ //只有三个点,求最近对距离
d1=Distance(S[low],S[low+1]);
d2=Distance(S[low+1],S[high]);
d3=Distance(S[low],S[high]);
if((d1<d2)&&(d1<d3)){
o1.first=S[low];
o1.second=S[low+1];
return o1;
}else if(d2<d3){
o2.first=S[low+1];
o2.second=S[high];
return o2;
}else{
o3.first=S[low];
o3.second=S[high];
return o3;
}
}
int mid=(low+high)/2;//计算中间点 当high-low==1 mid=low,mid+1=high但这种情况已经在上面被返回了
o1=Closest(S,low,mid); //递归求解子问题①
o2=Closest(S,mid+1,high); //递归求解子问题②
d1=Distance(o1.first,o1.second);
d2=Distance(o2.first,o2.second);
if(d1<=d2){
d=d1;
o=o1;
}else{
d=d2;
o=o2;
}
index=0;
for(i=mid;(i>=low)&&(S[mid].x-s[i].x<d);i--){//建立点集合P1
P[index++]=S[i];
}
for(i=mid+1;(i<=high)&&(S[i].x-s[i].x<d);i++){//建立点集合P2
P[index++]=S[i];
}
sort(P,P+index,compy); //对集合P1和P2按y坐标升序排列
for(i=0;i<index;i++){ //依次处理集合P1和P2中的点
for(j=i+1;j<index;j++){
if(P[j].y-P[i].y>=d){ //超出y坐标的范围,点p[i]处理完毕
break;
}else{
d3=Distance(P[i],P[j]);
o3.first=P[i];
o3.second=P[j];
if(d3<d){
d=d3;
o=o3;
}
}
}
}
return o;
}
int main(){
srand(time(NULL));
int n;
cout<<"Please input the number of points.\n";
cin>>n;
for(int i=0;i<n;i++){
s[i].x=rand()%1000;
s[i].y=rand()%1000;
cout<<s[i].x<<" "<<s[i].y<<endl;
}
cout<<"to sort"<<endl;
sort(s,s+n,compx); //对集合P1和P2按y坐标升序排列
for(int i=0;i<n;i++){
cout<<s[i].x<<" "<<s[i].y<<endl;
}
cout<<"have sorted"<<endl;
pair<point,point> o;
cout<<"Divide and conquer\n";
o = Closest(s,0,n);
double mind,mind1;
mind = Distance(o.first,o.second);
cout<<mind<<endl;
cout<<"("<<o.first.x<<", "<<o.first.y<<")\n";
cout<<"("<<o.second.x<<", "<<o.second.y<<")\n";
cout<<"brute force method\n";
mind1=2*mind;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i!=j){
if(Distance(s[i],s[j])<mind1){
o.first=s[i];
o.second=s[j];
mind1 = Distance(s[i],s[j]);
}
}
}
}
cout<<mind<<endl;
cout<<"("<<o.first.x<<", "<<o.first.y<<")\n";
cout<<"("<<o.second.x<<", "<<o.second.y<<")\n";
return 0;
}