普通方法,超时了。
#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坐标排序后,找出某个基准点将这堆点分为左右两个集合,大问题(寻找这堆点的最小距离)就分解为找左右两个集合里面最小问题,还加一个特殊情况(可能是左边某点和右边某点的距离是最小的)。这个题就是看你怎么处理这个特殊情况了。