码迷,mamicode.com
首页 > 其他好文 > 详细

【hdoj 1007】最近点对

时间:2015-05-01 18:48:19      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:hdoj   c++   最近点对   

题目:传送门

解答:直接暴力求解肯定会超时。此题核心就是求出来最近的一对点之间的距离,即最近点对算法

简要来说就是利用分治的思想,左半边的最小距离,与右半边的最小距离比较,得到一个mindist。再遍历分界线左右 mindist 范围内点的间距,取最小值。

这样,需要暴力的只有分界线周围的点。但是我第一次提交版本还是超时。询问之后是因为优化不够,写在trick中。

这里一些trick:

  1. 分界线:不一定是距离上的等分,根据 x 轴位置排序后进行数量上的等分(取最中间的左右更好;
  2. 取中点暴力时,切记不要与自身比较(距离为0);
  3. 除非有 string,不然不要用 cin,scanf 会快上很多;
  4. 这个我一直很想吐槽……数据精度,做 oj 就别用 float 了,直接上 double(困扰我好久);
  5. 浮点数(float,double)是不存在完全相等的(参见这里)。可以用eps(一般为1e-6, 1e-8),利用 fabs(abs是整数取绝对值)判断范围是否小于 eps.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <math.h>
#include <string>
#include <string.h>

#define MAXDIST 1000000

using namespace std;

struct Point{
    double x;
    double y;
};

int n;
double x, y;
bool tag;
Point tmp;
double eps = 1e-8;

Point gao[100005];

bool cmpxy (const Point a, const Point b)
{
    if(a.x != b.x)
    {
        return a.x < b.x;
    }
    else
    {
        return a.y < b.y;
    }
}

bool cmpx (const Point a, const Point b)
{
    return a.x < b.x;
}

bool cmpy (const Point a, const Point b)
{
    return a.y < b.y;
}

double dist(const Point a, const Point b)
{
    return ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

double nearestPair(int head, int tail)
{
    if(head == tail)
    {
        return MAXDIST;
    }

    if(head + 1 == tail)
    {
        return dist(gao[head], gao[tail]);
    }

    int mid = (head + tail) >> 1;
    double d1 = nearestPair(head, mid);
    double d2 = nearestPair(mid + 1, tail);

    double mindist = d1 > d2 ? d2 : d1;

    for(int i = head; i<=tail; i++)
    {
        // 不能和自身比较,否则距离为 0
        if(i != mid && gao[i].x > (gao[mid].x - mindist) && gao[i].x < (gao[mid].x + mindist))
        {
            if(dist(gao[i], gao[mid]) < mindist)
                mindist = dist(gao[i], gao[mid]);
        }
    }

    return mindist;
}

int main()
{
    while(cin>>n && n!= 0)
    {
        memset(gao, 0, sizeof(gao));
        tag = false;

        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf", &x, &y);
            tmp.x = x;
            tmp.y = y;
            gao[i] = tmp;
        }

        sort(gao, gao + n, cmpxy);
        for(int i=0; i < n-1; i++)
        {
            if(fabs(gao[i].x - gao[i+1].x) < eps && fabs(gao[i].y - gao[i+1].y) < eps)
                tag = true;
        }
        
        if(tag)
        {
            cout<<"0.00"<<endl;
            continue;
        }
        else
        {
            double d = nearestPair(0, n-1);
            printf("%.2f\n", sqrt(d)/2);
        }
    }
    return 0;
}

【hdoj 1007】最近点对

标签:hdoj   c++   最近点对   

原文地址:http://blog.csdn.net/ironyoung/article/details/45420493

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!