普通方法,超时了。
#include<iostream> #include <iomanip> #include<math.h> #include<vector> using namespace std; class Point { public: double douX; double douY; Point():douX(0),douY(0) { } Point(double x, double y):douX(x),douY(y) { } }; int main() { int iPointNum; double dX, dY; while(cin >> iPointNum) { if(0 == iPointNum) { return 0; } else { vector<Point> vecPoint(iPointNum); double douMinDistance = 0; double douDistance = 0; for(int i = 0; i < iPointNum; i++) { cin >> dX >> dY; Point p(dX, dY); vecPoint[i] = p; }//for_loop for(int j = 0; j < iPointNum; j++) { for(int k = j + 1; k < iPointNum; k++) { double douXDistence = fabs(vecPoint[k].douX - vecPoint[j].douX); double douYDistence = fabs(vecPoint[k].douY - vecPoint[j].douY); douDistance = sqrt(pow(douXDistence, 2) + pow(douYDistence, 2)); if(douDistance < douMinDistance) { douMinDistance = douDistance; } }//for_loop }//for_loop cout << fixed << setprecision(2) << douMinDistance << endl; }//if_loop }//while_loop return 0; }
模仿网上一个分治法,还是超时了。
#include<iostream> #include <iomanip> #include<math.h> #include<vector> #include<algorithm> using namespace std; class Point { public: double douX; double douY; Point():douX(0),douY(0) { } Point(double x, double y):douX(x),douY(y) { } }; double P2PDistance(Point pa, Point pb) { double douXDistence = fabs(pa.douX - pb.douX); double douYDistence = fabs(pa.douY - pb.douY); double douDistance = sqrt(pow(douXDistence, 2) + pow(douYDistence, 2)); return douDistance; } double MinDistance(double a, double b) { return a < b ? a : b; } bool CompByX(Point pa, Point pb) { if(pa.douX < pb.douX) { return true; } else { return false; } } bool CompByY(Point pa, Point pb) { if(pa.douY < pb.douY) { return true; } else { return false; } } double GetMinDistance(int begin, int end, vector<Point>& vecPoint) { if(begin == end) { return 0; } else if(begin + 1 == end) { return P2PDistance(vecPoint[begin], vecPoint[end]); } else if(begin + 2 == end) { double dist1 = P2PDistance(vecPoint[begin], vecPoint[begin+1]); double dist2 = P2PDistance(vecPoint[begin+1], vecPoint[begin+2]); double dist3 = P2PDistance(vecPoint[begin], vecPoint[begin+2]); return MinDistance(MinDistance(dist1,dist2),dist3); } int mid = (begin + end)/2; int iMinDist = MinDistance( GetMinDistance(begin, mid, vecPoint), GetMinDistance(mid + 1, end, vecPoint) ); //vector里面的元素已经X排序 vector<Point> vecPointX; for(int i = begin; i < end; i++) { if(fabs(vecPoint[i].douX - vecPoint[mid].douX) < iMinDist) { vecPointX.push_back(vecPoint[i]); //X距离小于iMinDist,有可能 } }//for_loop vector<Point> vecPointY; sort(vecPointX.begin(), vecPointX.end(), CompByY); mid = (vecPointX.size()) / 2; for(int i = 0; i < vecPointX.size(); i++) { if(fabs(vecPointX[i].douY - vecPointX[mid].douY) < iMinDist) { vecPointY.push_back(vecPointX[i]); //Y距离小于iMinDist,有可能 } }//for_loop for(int i = 0; i < vecPointY.size(); i++) //查看上述那些“可能”是否是会出现 { double dist = P2PDistance(vecPointY[i], vecPointX[mid]); if(dist < iMinDist) { iMinDist = dist; } }//for_loop return iMinDist; } int main() { int iPointNum; double dX, dY; while(cin >> iPointNum) { if(0 == iPointNum) { return 0; } else { vector<Point> vecPoint(iPointNum); double douMinDistance = 0; for(int i = 0; i < iPointNum; i++) { cin >> dX >> dY; Point p(dX, dY); vecPoint[i] = p; }//for_loop sort(vecPoint.begin(), vecPoint.end(), CompByX); //对X进行排序,进入GetMinDistance使用 douMinDistance = GetMinDistance(0, vecPoint.size() - 1, vecPoint); cout << fixed << setprecision(2) << douMinDistance << endl; }//if_loop }//while_loop return 0; }
题目:点击打开链接 ---- 最小套圈问题
参考答案: 点击打开链接 ---- 分治法求解
传统观的分治法,是将一个大问题分解成同样的小问题求解。这个里面有点状况,不能完全套用传统的方法。将一堆点按X坐标排序后,找出某个基准点将这堆点分为左右两个集合,大问题(寻找这堆点的最小距离)就分解为找左右两个集合里面最小问题,还加一个特殊情况(可能是左边某点和右边某点的距离是最小的)。这个题就是看你怎么处理这个特殊情况了。