到现在看着伪代码写不出来递归函数,不知道计算过程应该放在哪儿,我觉得是够菜了,一个一维的求解弄一晚上。
菜的真实,菜的绝望。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
class pair{
public:
double dis;
int point1,point2;
operator<(const pair &p)
{
return dis<p.dis;
}
};
void Swap(double *a,double *b)
{
double tep=*a;
*a=*b;
*b=tep;
}
int Partition(double *a,int l,int r,double value)
{
double tep=value;
int i=l,j=r;
while(i<j)
{
while(a[i]<tep && i<r) i++;
while(a[j]>tep && j>l) j--;
if(i<j)
Swap(a+i,a+j);
}
return j;
}
void quicksort(double *a,int l,int r)
{
if(l>=r)
return ;
int select=rand()%(r-l+1)+l;
double tep=a[select];
int j=Partition(a,l,r,tep);
quicksort(a,l,j);
quicksort(a,j+1,r);
}
double Select(double *a,int l,int r,int rank)
{
if(r-l+1<=75)
{
quicksort(a,l,r);
return a[l+rank-1];
}
for(int i=0;i<=(r-l-4)/5;i++)
{
quicksort(a,l+i*5,l+5*i+4);
Swap(a+l+5*i+2,a+l+i);
}
double mid=Select(a,l,l+(r-l-4)/5,(r-l-4)/10);
int index=Partition(a,l,r,mid);
int surplus=index-l+1;
if(surplus>=rank)
return Select(a,l,index,rank);
else
return Select(a,index+1,r,surplus-rank);
}
int MAX(double *a,int l,int r)
{
double m=-1e7;
int f=0;
for(int i=l;i<=r;i++)
if(m<a[i])
m=a[i],f=i;
return f;
}
double MIN(double *a,int l,int r)
{
double m=1e7,f=0;
for(int i=l;i<=r;i++)
if(m>a[i])
m=a[i],f=i;
return f;
}
pair cloest(double *a,int l,int r)
{
pair ans={1e7,l,r};
if(r-l<1)
return ans;
double mid=Select(a,l,r,(r-l+1)/2);
int index=Partition(a,l,r,mid);
pair dis1=cloest(a,l,index),dis2=cloest(a,index+1,r);
int Max=MAX(a,l,index);
int Min=MIN(a,index+1,r);
double t=a[Min]-a[Max];
pair tt={t,Max,Min};
if(dis1.dis<dis2.dis)
{
if(dis1.dis<tt.dis)
ans=dis1;
else
ans=tt;
}
else
{
if(tt.dis<dis2.dis)
ans=tt;
else
ans=dis2;
}
return ans;
}
int main()
{
int n;
double p[10005];
pair dis;
printf("Please input the number of points\n");
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf",&p[i]);
dis=cloest(p,0,n-1);
printf("%.3lf p1:%d p2:%d\n",dis.dis,dis.point1,dis.point2);
return 0;
}
二维的明天补上
#include<bits/stdc++.h>
using namespace std;
class PointX{
public:
int no;
double x,y;
int operator<(const PointX &p)
{
return x<p.x;
}
int operator>(const PointX &p)
{
return x>p.x;
}
};
class PointY{
public:
int no_X;
double x,y;
int operator<(const PointY &p)
{
return y<p.y;
}
int operator>(const PointY &p)
{
return y>p.y;
}
};
template<typename T>
void Merge(T a[],T b[],int l,int mid,int r)//give a to b
{
int i=l,j=mid+1;
int st=l;
while(i<=mid && j<=r)
{
if(a[i]<a[j]) b[st++]=a[i++];
else b[st++]=a[j++];
}
while(i<=mid) b[st++]=a[i++];
while(j<=r) b[st++]=a[j++];
}
template<typename T>
void Swap(T *a,T *b)
{
T temp=*a;
*a=*b;
*b=temp;
}
template<typename T>
void quicksort(T *a,int l,int r)
{
if(l>=r)
return ;
int i=l,j=r;
int select=rand()%(r-l+1)+l;
T v=a[select];
while(1)
{
while(a[i]<v && i<r) i++;
while(a[j]>v && j>l) j--;
if(i>=j) break;
Swap(a+i,a+j);
}
quicksort(a,l,j);
quicksort(a,j+1,r);
}
template<typename T>
double Distance(T a,T b)
{
double xx=a.x-b.x;
double yy=a.y-b.y;
return sqrt(xx*xx+yy*yy);
}
void closest(PointX *x,PointY *y,PointY *z,int l,int r,PointX &ans1,PointX &ans2,double &dis)
{
if(r-l==1)
{
ans1=x[l];
ans2=x[r];
dis=Distance(x[l],x[r]);
return ;
}
if(r-l==2)
{
double dis1=Distance(x[l],x[l+1]);//l,l+1
double dis2=Distance(x[l],x[r]);//l,r
double dis3=Distance(x[l+1],x[r]);//l+1,r
if(dis1>dis2){
if(dis1>dis3) {ans1=x[l]; ans2=x[l+1]; dis=dis1;}
else {ans1=x[l+1];ans2=x[r];dis=dis3;}
}
else{
if(dis2>dis3){ans1=x[l];ans2=x[r];dis=dis2;}
else{ans1=x[l+1];ans2=x[r];dis=dis3;};
}
return ;
}
int mid=(l+r)/2;
int s=l,t=mid+1;
for(int i=l;i<=r;i++)
{
if(y[i].no_X>mid) z[t++]=y[i];
else z[s++]=y[i];
}
closest(x,z,y,l,mid,ans1,ans2,dis);
double an;
PointX xx,yy;
closest(x,z,y,mid+1,r,xx,yy,an);
Merge(z,y,l,mid,r);
if(an>dis){
dis=an;
ans1=xx; ans2=yy;
}
int st=l;
for(int i=l;i<=r;i++)
{
if(fabs(y[i].x-x[mid].x)<dis)
z[st++]=y[i];
}
for(int i=l;i<st;i++)
{
for(int j=i+1;j<st && z[j].y-z[i].y<dis;j++)
{
double tep=Distance(z[i],z[j]);
if(tep<dis)
{
dis=tep;
ans1=x[z[i].no_X];ans2=x[z[j].no_X];
}
}
}
}
void calculate(PointX *x,int n,PointX &ans1,PointX &ans2,double &dis)
{
if(n<2)
return ;
quicksort(x,0,n-1);
PointY *y=new PointY[n];
for(int i=0;i<n;i++)
{
y[i].no_X=i;
y[i].x=x[i].x;
y[i].y=x[i].y;
}
quicksort(y,0,n-1);
PointY *z=new PointY[n];
closest(x,y,z,0,n-1,ans1,ans2,dis);
delete y;
delete z;
}
int main()
{
int n;
PointX x[1000];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
x[i].no=i;
scanf("%lf%lf",&x[i].x,&x[i].y);
}
PointX ans1,ans2;
double dis;
calculate(x,n,ans1,ans2,dis);
printf("The smallest Distance is %lf\n",dis);
printf("The first point's coordinate: x:%lf y:%lf\n",ans1.x,ans1.y);
printf("The second point's coordinate: x:%lf y:%lf\n",ans2.x,ans2.y);
return 0;
}
基本是按书上的做法来的,就是写起来有点复杂啊,自己实现又写不出来,只能看看博客讨讨生活。