1 条题解
-
0
C++ :
////2d10-2 二维最邻近点对问题 // //#include<time.h> //#include<iostream> //#include<cmath> // //using namespace std; //const int M=50; // ////用类PointX和PointY表示依x坐标和y坐标排好序的点 //class PointX { //public: // int operator<=(PointX a)const // { return (x<=a.x); } // int ID; //点编号 // float x,y; //点坐标 //}; // //class PointY { //public: // int operator<=(PointY a)const // { return(y<=a.y); } // int p; //同一点在数组x中的坐标 // float x,y; //点坐标 //}; // //float Random(); //template <class Type> //float dis(const Type&u,const Type&v); // //bool Cpair2(PointX X[], int n,PointX& a,PointX& b, float& d); //void closest(PointX X[],PointY Y[],PointY Z[], int l, int r,PointX& a,PointX& b,float& d); // //template <typename Type> //void Copy(Type a[],Type b[], int left,int right); // //template <class Type> //void Merge(Type c[],Type d[],int l,int m,int r); // //template <class Type> //void MergeSort(Type a[],Type b[],int left,int right); // //int main() //{ // srand((unsigned)time(NULL)); // int length; // // cout<<"请输入点对数:"; // cin>>length; // // PointX X[M]; // cout<<"随机生成的二维点对为:"<<endl; // // for(int i=0;i<length;i++) // { // X[i].ID=i; // X[i].x=Random(); // X[i].y=Random(); // cout<<"("<<X[i].x<<","<<X[i].y<<") "; // } // // PointX a; // PointX b; // float d; // // Cpair2(X,length,a,b,d); // // cout<<endl; // cout<<"最邻近点对为:("<<a.x<<","<<a.y<<")和("<<b.x<<","<<b.y<<") "<<endl; // cout<<"最邻近距离为: "<<d<<endl; // getchar(); // return 0; //} // //float Random() //{ // float result=rand()%10000; // return result*0.01; //} // ////平面上任意两点u和v之间的距离可计算如下 //template <class Type> //inline float dis(const Type& u,const Type& v) //{ // float dx=u.x-v.x; // float dy=u.y-v.y; // return sqrt(dx*dx+dy*dy); //} // //bool Cpair2(PointX X[], int n,PointX& a,PointX& b,float& d) //{ // if(n<2) return false; // // PointX* tmpX = new PointX[n]; // MergeSort(X,tmpX,0,n-1); // // PointY* Y=new PointY[n]; // for(int i=0;i<n;i++) //将数组X中的点复制到数组Y中 // { // Y[i].p=i; // Y[i].x=X[i].x; // Y[i].y=X[i].y; // } // // PointY* tmpY = new PointY[n]; // MergeSort(Y,tmpY,0,n-1); // // PointY* Z=new PointY[n]; // closest(X,Y,Z,0,n-1,a,b,d); // // delete []Y; // delete []Z; // delete []tmpX; // delete []tmpY; // return true; //} //void closest(PointX X[],PointY Y[],PointY Z[], int l, int r,PointX& a,PointX& b,float& d) //{ // if(r-l==1) //两点的情形 // { // a=X[l]; // b=X[r]; // d=dis(X[l],X[r]); // return; // } // // if(r-l==2) //3点的情形 // { // float d1=dis(X[l],X[l+1]); // float d2=dis(X[l+1],X[r]); // float d3=dis(X[l],X[r]); // // if(d1<=d2 && d1<=d3) // { // a=X[l]; // b=X[l+1]; // d=d1; // return; // } // // if(d2<=d3) // { // a=X[l+1]; // b=X[r]; // d=d2; // } // else { // a=X[l]; // b=X[r]; // d=d3; // } // return; // } // // //多于3点的情形,用分治法 // int m=(l+r)/2; // int f=l,g=m+1; // // //在算法预处理阶段,将数组X中的点依x坐标排序,将数组Y中的点依y坐标排序 // //算法分割阶段,将子数组X[l:r]均匀划分成两个不想交的子集,取m=(l+r)/2 // //X[l:m]和X[m+1:r]就是满足要求的分割。 // for(int i=l;i<=r;i++) // { // if(Y[i].p>m) Z[g++]=Y[i]; // else Z[f++]=Y[i]; // } // // closest(X,Z,Y,l,m,a,b,d); // float dr; // // PointX ar,br; // closest(X,Z,Y,m+1,r,ar,br,dr); // // if(dr<d) // { // a=ar; // b=br; // d=dr; // } // // Merge(Z,Y,l,m,r);//重构数组Y // // //d矩形条内的点置于Z中 // int k=l; // for(int i=l;i<=r;i++) // { // if(fabs(X[m].x-Y[i].x)<d) // { // Z[k++]=Y[i]; // } // } // // //搜索Z[l:k-1] // for(int i=l;i<k;i++) // { // for(int j=i+1;j<k && Z[j].y-Z[i].y<d;j++) // { // float dp=dis(Z[i],Z[j]); // if(dp<d) // { // d=dp; // a=X[Z[i].p]; // b=X[Z[j].p]; // } // } // } //} // //template <class Type> //void Merge(Type c[],Type d[],int l,int m,int r) //{ // int i = l,j = m + 1,k = l; // while((i<=m)&&(j<=r)) // { // if(c[i]<=c[j]) // { // d[k++] = c[i++]; // } // else // { // d[k++] = c[j++]; // } // } // // if(i>m) // { // for(int q=j; q<=r; q++) // { // d[k++] = c[q]; // } // } // else // { // for(int q=i; q<=m; q++) // { // d[k++] = c[q]; // } // } //} // //template <class Type> //void MergeSort(Type a[],Type b[],int left,int right) //{ // if(left<right) // { // int i = (left + right)/2; // MergeSort(a,b,left,i); // MergeSort(a,b,i+1,right); // Merge(a,b,left,i,right);//合并到数组b // Copy(a,b,left,right);//复制回数组a // } //} // //template <typename Type> //void Copy(Type a[],Type b[], int left,int right) //{ // for(int i=left;i<=right;i++) // a[i]=b[i]; //} #include<iostream> #include<cmath> using namespace std; const int M=50; //用类PointX和PointY表示依x坐标和y坐标排好序的点 class PointX { public: int operator<=(PointX a)const { return (x<=a.x); } int ID; //点编号 float x,y; //点坐标 }; class PointY { public: int operator<=(PointY a)const { return(y<=a.y); } int p; //同一点在数组x中的坐标 float x,y; //点坐标 }; int main() { int length; bool Cpair2(PointX X[], int n,PointX& a,PointX& b,float& d); // cout<<"请输入点对数:"; cin>>length; PointX X[M]; // cout<<"请输入"<<length<<"对点:"; for(int i=0;i<length;i++) scanf("%f,%f",&X[i].x,&X[i].y); PointX a; PointX b; float d; Cpair2(X,length,a,b,d); //cout<<endl; //cout<<"最邻近点对为:"; cout<<"("<<a.x <<","<<a.y <<")(" <<b.x <<","<<b.y <<")"<<endl; //cout<<"最邻近距离为: "; cout<<d<<endl; return 0; } //平面上任意两点u和v之间的距离计算如下 template <class Type> inline float dis(const Type& u,const Type& v) { float dx=u.x-v.x; float dy=u.y-v.y; return sqrt(dx*dx+dy*dy); } template <class Type> void Merge(Type c[],Type d[],int l,int m,int r)//重构数组Y { int i = l,j = m + 1,k = l; while((i<=m)&&(j<=r)) { if(c[i]<=c[j]) { d[k++]=c[i++]; } else { d[k++]=c[j++]; } } if(i>m) { for(int q=j;q<=r;q++) { d[k++]=c[q]; } } else { for(int q=i;q<=m;q++) { d[k++]=c[q]; } } } void closest(PointX X[],PointY Y[],PointY Z[], int l, int r,PointX& a,PointX& b,float& d) { if(r-l==1) //两点的情形 { a=X[l]; b=X[r]; d=dis(X[l],X[r]); return; } if(r-l==2) //3点的情形 { float d1=dis(X[l],X[l+1]); float d2=dis(X[l+1],X[r]); float d3=dis(X[l],X[r]); if(d1<=d2 && d1<=d3) { a=X[l]; b=X[l+1]; d=d1; return; } if(d2<=d3) { a=X[l+1]; b=X[r]; d=d2; } else { a=X[l]; b=X[r]; d=d3; } return; } //多于3点的情形,用分治法 int m=(l+r)/2; int f=l,g=m+1; //在算法预处理阶段,将数组X中的点依x坐标排序,将数组Y中的点依y坐标排序 //算法分割阶段,将子数组X[l:r]均匀划分成两个不想交的子集,取m=(l+r)/2 //X[l:m]和X[m+1:r]就是满足要求的分割。 for(int i=l;i<=r;i++) { if(Y[i].p>m) Z[g++]=Y[i]; else Z[f++]=Y[i]; } closest(X,Z,Y,l,m,a,b,d); float dr; PointX ar,br; closest(X,Z,Y,m+1,r,ar,br,dr); if(dr<d) { a=ar; b=br; d=dr; } Merge(Z,Y,l,m,r);//重构数组Y //d矩形条内的点置于Z中 int k=l; for(int i1=l;i1<=r;i1++) { if(fabs(X[m].x-Y[i1].x)<d) { Z[k++]=Y[i1]; } } //搜索Z[l:k-1] for(int i2=1;i2<k;i2++) { for(int j=i2+1;j<k && Z[j].y-Z[i2].y<d;j++) { float dp=dis(Z[i2],Z[j]); if(dp<d) { d=dp; a=X[Z[i2].p]; b=X[Z[j].p]; } } } } template <class Type> void MergeSort(Type a[],Type b[],int left,int right) { if(left<right) { int i = (left + right)/2; MergeSort(a,b,left,i); MergeSort(a,b,i+1,right); Merge(a,b,left,i,right);//合并到数组b Copy(a,b,left,right);//复制回数组a } } template <typename Type> void Copy(Type a[],Type b[], int left,int right) { for(int i=left;i<=right;i++) a[i]=b[i]; } bool Cpair2(PointX X[], int n,PointX& a,PointX& b,float& d) { if(n<2) return false; PointX* tmpX = new PointX[n]; MergeSort(X,tmpX,0,n-1); PointY* Y=new PointY[n]; for(int i=0;i<n;i++) //将数组X中的点复制到数组Y中 { Y[i].p=i; Y[i].x=X[i].x; Y[i].y=X[i].y; } PointY* tmpY = new PointY[n]; MergeSort(Y,tmpY,0,n-1); PointY* Z=new PointY[n]; closest(X,Y,Z,0,n-1,a,b,d); delete []Y; delete []Z; delete []tmpX; delete []tmpY; return true; }
- 1
信息
- ID
- 3138
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者