zoukankan      html  css  js  c++  java
  • 最近点对问题 POJ 3714 Raid && HDOJ 1007 Quoit Design

    题意:有n个点,问其中某一对点的距离最小是多少

    分析:分治法解决问题:先按照x坐标排序,求解(left, mid)和(mid+1, right)范围的最小值,然后类似区间合并,分离mid左右的点也求最小值

    POJ 3714

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    const int N = 1e5 + 5;
    const double INF = 1e100;
    struct Point {
        double x, y;
        bool flag;
        bool operator < (const Point &rhs) const {
            return x < rhs.x;
        }
    };
    Point point[N*2];
    int idy[N*2];
    int n;
    
    bool cmp_y(int i, int j) {
        return point[i].y < point[j].y;
    }
    
    double squ(double x) {
        return x * x;
    }
    
    double get_dist(Point &a, Point &b) {
        if (a.flag == b.flag) {
            return INF;
        }
        return sqrt (squ (a.x - b.x) + squ (a.y - b.y));
    }
    
    double min_dist(int left, int right) {
        if (left == right) {
            return INF;
        }
        else if (right - left == 1) {
            return get_dist (point[left], point[right]);
        } else {
            int mid = left + right >> 1;
            double ret = std::min (min_dist (left, mid), min_dist (mid + 1, right));
            if (ret == 0) {
                return ret;
            }
            int endy = 0;
            for (int i=mid; i>=left&&point[mid].x-point[i].x<=ret; --i) {
                idy[endy++] = i;
            }
            for (int i=mid+1; i<=right&&point[i].x-point[mid+1].x<=ret; ++i) {
                idy[endy++] = i;
            }
            std::sort (idy, idy+endy, cmp_y);
            for (int i=0; i<endy; ++i) {
                for (int j=i+1; j<endy&&point[j].y-point[i].y<ret; ++j) {
                    ret = std::min (ret, get_dist (point[i], point[j]));
                }
            }
            return ret;
        }
    }
    
    int main() {
        int T; scanf ("%d", &T);
        while (T--) {
            scanf ("%d", &n);
            for (int i=0; i<2*n; ++i) {
                scanf ("%lf%lf", &point[i].x, &point[i].y);
                if (i < n) {
                    point[i].flag = false;
                } else {
                    point[i].flag = true;
                }
            }
            std::sort (point, point+2*n);
            printf ("%.3f
    ", min_dist (0, 2 * n - 1));
        }
    
        return 0;
    }

    HDOJ 1007

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    const int N = 1e5 + 5;
    const double INF = 1e100;
    struct Point {
        double x, y;
    };
    Point point[N], py[N];
    int n;
    
    bool cmp_x(const Point &a, const Point &b) {
        return a.x < b.x;
    }
    bool cmp_y(const Point &a, const Point &b) {
        return a.y < b.y;
    }
    
    double squ(double x) {
        return x * x;
    }
    
    double get_dist(Point &a, Point &b) {
        return sqrt (squ (a.x - b.x) + squ (a.y - b.y));
    }
    
    double min_dist(int left, int right) {
        if (left + 1 == right) {
            return get_dist (point[left], point[right]);
        } else if (left + 2 == right) {
            return std::min (get_dist (point[left], point[left+1]), 
                    std::min (get_dist (point[left], point[right]), get_dist (point[left+1], point[right])));
        } else {
            int mid = left + right >> 1;
            double ret = std::min (min_dist (left, mid), min_dist (mid + 1, right));
            int cnt = 0;
            for (int i=mid; i>=left&&point[mid].x-point[i].x<=ret; --i) {
                py[cnt++] = point[i];
            }
            for (int i=mid+1; i<=right&&point[i].x-point[mid+1].x<=ret; ++i) {
                py[cnt++] = point[i];
            }
            std::sort (py, py+cnt, cmp_y);
            for (int i=0; i<cnt; ++i) {
                for (int j=i+1; j<cnt&&py[j].y-py[i].y<ret; ++j) {
                    ret = std::min (ret, get_dist (py[i], py[j]));
                }
            }
            return ret;
        }
    }
    
    int main() {
        while (scanf ("%d", &n) == 1) {
            if (!n) {
                break;
            }
            for (int i=0; i<n; ++i) {
                scanf ("%lf%lf", &point[i].x, &point[i].y);
            }
            std::sort (point, point+n, cmp_x);
            printf ("%.2f
    ", min_dist (0, n - 1) / 2);
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    第三天 moyax
    mkfs.ext3 option
    write file to stroage trigger kernel warning
    download fomat install rootfs script
    custom usb-seriel udev relus for compatible usb-seriel devices using kermit
    Wifi Troughput Test using iperf
    learning uboot switch to standby system using button
    learning uboot support web http function in qca4531 cpu
    learngin uboot design parameter recovery mechanism
    learning uboot auto switch to stanbdy system in qca4531 cpu
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5340775.html
Copyright © 2011-2022 走看看