UVa 10245 - The Closest Pair Problem

题目链接: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;
}


你可能感兴趣的:(UVa 10245 - The Closest Pair Problem)