zoukankan      html  css  js  c++  java
  • 寻找最近点对

    算法导论上一个经典算法,讲解可看 http://yzmduncan.iteye.com/blog/1432880 

    AC代码的复杂度为 n*lgn*lgn,算法导论上讲还可以通过“预排序”,不用每次都按照y排序,复杂度可下降为n*lgn。

    http://acm.hdu.edu.cn/status.php  上可以AC。

    #include<stdio.h>
    #include<math.h>
    #include<algorithm>
    
    using namespace std;
    
    #define MAX 100005
    #define Inf 2e20
    
    struct Point {
        double x;
        double y;
    };
    
    Point a[MAX];
    Point tmp[MAX];
    
    int cmpX(Point a, Point b) {
        return a.x < b.x;
    }
    int cmpY(Point a, Point b) {
        return a.y < b.y;
    }
    
    double dis(Point* a, int i, int j) {
        return sqrt(
                (a[i].x - a[j].x) * (a[i].x - a[j].x)
                        + (a[i].y - a[j].y) * (a[i].y - a[j].y));
    }
    
    double minDis(int left, int right) {
        double d = Inf;
        if (left == right)
            return d;
        if (left + 1 == right) {
            return dis(a, left, right);
        }
        if (left + 2 == right) {
            return min(min(dis(a, left, left + 1), dis(a, left, right)),
                    dis(a, left + 1, right));
        }
    
        int mid = left + (right - left) / 2;
        double minLeft = minDis(left, mid);
        double minRight = minDis(mid + 1, right);
        d = min(minLeft, minRight);
    
        int k = 0;
        for (int i = left; i <= right; i++) {
            if (fabs(a[mid].x - a[i].x) <= d) {
                tmp[k].x = a[i].x;
                tmp[k].y = a[i].y;
                k++;
            }
        }
    
        sort(tmp, tmp + k, cmpY);
    
        for (int i = 0; i < k; i++) {
            //j<i+8优化,否则会超时
            for (int j = i + 1; j < k && j < i + 8; j++) {
                if (dis(tmp, i, j) < d) {
                    d = dis(tmp, i, j);
                }
            }
    
        }
        return d;
    
    }
    
    int main() {
        freopen("my.in", "r", stdin);
        int n;
        while (scanf("%d", &n) != EOF) {
            if (n == 0)
                break;
            for (int i = 0; i < n; i++) {
                scanf("%lf%lf", &a[i].x, &a[i].y);
            }
            sort(a, a + n, cmpX);
            double res = minDis(0, n - 1);
    
            printf("%.2lf
    ", res / 2);
        }
    
        return 0;
    }
  • 相关阅读:
    浏览器版本 / 设备系统 检测
    控制HTML页面内容不能选中的方法
    js 正则常用函数
    谁动了我的Mac ??
    有关使用 iview 表单验证的问题
    Object.defineProperty()
    AIX 查看CPU个数
    AIX sed
    df和du显示的磁盘空间使用情况不一致的原因及处理
    Informix ESQL/C使用游标的一个example
  • 原文地址:https://www.cnblogs.com/jdflyfly/p/3956624.html
Copyright © 2011-2022 走看看