zoukankan      html  css  js  c++  java
  • HDU-1007 Quoit Design

    题目大意:给你n个点,代表toy,求一个使得可以套住一个toy且只能套住一个toy的环的最大半径。

    解法:只需要求出所有点的最近点对的长度就可以解决了。但是如何求最近点对?
    最容易想到的就是暴力枚举所有点对,求出最小长度,然后就可以得到结果。但是复杂度为O(n^2)而这题n的范围是100000,必然不能通过。所以可以使用分治来解决这题。
    分治解决这个问题的复杂度为O(nlognlogn),所以是比较适合的。

    知道怎么做就可以上代码了。
    我直接跟这kuangbin的模板敲了一发。

    //time   memery
    //1060ms 4572k
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define INF 1e18
    const int maxn = 100000 + 10;
    typedef struct{
        double x, y;
    }Coord;
    Coord p[maxn], tmp[maxn];
    bool cmp1(Coord a, Coord b){
        if(a.x != b.x)
            return a.x < b.x;
        else
            return a.y < b.y;
    }
    bool cmp2(Coord a, Coord b){
        if(a.y != b.y)
            return a.y < b.y;
        else
            return a.x < b.x;
    }
    inline double f(int x){
        return (x > 0 ? x : -x);
    }
    inline double Min(double a, double b){
        return (a < b ? a : b);
    }
    inline double Dist(Coord a, Coord b){
        return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
    double Cal_Closest(int left, int right){
        double d = INF;
    
        if(left == right){
            return d;
        }
        if(left + 1 == right){
            return Dist(p[left], p[right]);
        }
    
        int mid = (left + right) >> 1;
        double d1 = Cal_Closest(left, mid);
        double d2 = Cal_Closest(mid + 1, right);
        d = Min(d1, d2);
    
        int k = 0;
        for(int i = left; i <= right; ++i){
            if(f(p[mid].x - p[i].x) <= d){
                tmp[k++] = p[i];
            }
        }
        sort(tmp, tmp + k, cmp2);
    
        for(int i = 0; i < k; ++i){
            for(int j = i + 1; j < k && tmp[j].y - tmp[i].y < d; ++j){
                d = Min(d, Dist(tmp[i], tmp[j]));
            }
        }
    
        return d;
    }
    int main()
    {
        int n;
        while(scanf("%d", &n) && n){
            memset(p, 0, sizeof(p));
            for(int i = 0; i < n; ++i){
                scanf("%lf%lf", &p[i].x, &p[i].y);
            }
            sort(p, p + n, cmp1);
    
            printf("%.2lf
    ", Cal_Closest(0, n - 1) / 2);
        }
        return 0;
    }
  • 相关阅读:
    JqGrid在IE8中表头不能分组的解决办法
    Task 异步小技巧
    封装好的socket,拿去用
    反射 实现不同模型相同属性赋值 第二集(automapper)
    .net破解二(修改dll)
    .net破解一(反编译,反混淆-剥壳)
    c/s 自动升级(WebService)
    反射实现不同模型相同属性赋值
    row_number() over()分页查询
    SQL函数
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179479.html
Copyright © 2011-2022 走看看