题目链接:UVa 10245 - The Closest Pair Problem
这题坑了我一晚上。
首先说明纯暴力是不行的。
那就得优化,分治法。
然后我就开始无限循环TLE了。。。
最后发现是点的坐标的问题,不是整型。。至少题目中没有说。换成double就好了。类型问题出现TLE错误这是碰见的第二次了,还是不长记性。哎。
先按y坐标或者x坐标排一下序,然后开始把大问题分解成一个个小问题解决。最短距离无非是三种情况,一种是在左边的小问题中求得,一种是在右边的小问题中求得,最后一种是一个点在左边一个点在右边。计算最后一种情况的时候就发现之前排序的作用了(可以提前退出循环)。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;
const int MAX_N = 10000 + 10;
const double _INFINITY = 10000;
const double e = 1e-9;
int n;
struct point
{
double x,y;
};
point p[MAX_N];
bool cmp(point i,point j)
{
return i.y < j.y;
}
double cal_sqrt(int i,int j)
{
return sqrt((p[i].x - p[j].x) * (p[i].x - p[j].x) +
(p[i].y - p[j].y) * (p[i].y - p[j].y));
}
double solve(int l,int r)//分治
{
if(r - l > 2)
{
int mid = (l + r) / 2;
double _min = min(solve(l,mid),solve(mid,r));
for(int i = l;i < mid;i++)
{
for(int j = mid;j < r;j++)
{
if((p[j].y - p[i].y) - _min > e)
break;
double temp = cal_sqrt(i,j);
if(temp - _min < e)
_min = temp;
}
}
return _min;
}
else if(r - l == 1)
return _INFINITY + 10;
else
return cal_sqrt(l,l + 1);
}
int main()
{
while(cin>>n,n)
{
for(int i = 0;i < n;i++)
cin>>p[i].x>>p[i].y;
sort(p,p + n,cmp);
double res = solve(0,n);
if(res - _INFINITY < e)
cout<<fixed<<setprecision(4)<<res<<endl;
else
cout<<"INFINITY"<<endl;
}
return 0;
}