zoukankan      html  css  js  c++  java
  • HDU 2215 Maple trees

    增量法的最小包围圈算法,不会……

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const double EPS = 1e-10;
    inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
    struct Point {
        double x, y;
        Point() {}
        Point(double x, double y) : x(x),y(y) {}
        bool operator < (Point a) const { return sgn(x - a.x) < 0 || sgn(x - a.x) == 0 && sgn(y - a.y) < 0;}
        bool operator == (Point a) const { return sgn(x - a.x) == 0 && sgn(y - a.y) == 0;}
        Point operator + (Point a) const { return Point(x + a.x, y + a.y);}
        Point operator - (Point a) const { return Point(x - a.x, y - a.y);}
        Point operator * (double p) const { return Point(x * p, y * p);}
        Point operator / (double p) const { return Point(x / p, y / p);}
    } ;
    typedef Point Vec;
    inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
    inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
    inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
    inline double vecLen(Vec x) { return sqrt(dotDet(x, x));}
    inline Point normal(Vec x) { return Point(-x.y, x.x) / vecLen(x);}
    Point lineIntersect(Point P, Vec v, Point Q, Vec w) {
        Vec u = P - Q;
        double t = crossDet(w, u) / crossDet(v, w);
        return P + v * t;
    }
    inline Point getMid(Point a, Point b) { return (a + b) / 2.0;}
    struct Circle {
        Point c;
        double r;
        Circle() {}
        Circle(Point c, double r) : c(c), r(r) {}
    } ;
    
    Circle getCircle(Point a, Point b, Point c) {
        Vec v1 = b - a, v2 = c - a;
        if (sgn(dotDet(b - a, c - a)) <= 0) return Circle(getMid(b, c), vecLen(b - c) / 2.0);
        if (sgn(dotDet(a - b, c - b)) <= 0) return Circle(getMid(a, c), vecLen(a - c) / 2.0);
        if (sgn(dotDet(a - c, b - c)) <= 0) return Circle(getMid(a, b), vecLen(a - b) / 2.0);
        Point ip = lineIntersect(getMid(a, b), normal(v1), getMid(a, c), normal(v2));
        return Circle(ip, vecLen(ip - a));
    }
    int andrew(Point *pt, int n, Point *ch) {
        sort(pt, pt + n);
        int m = 0;
        for (int i = 0; i < n; i++) {
            while (m > 1 && sgn(crossDet(ch[m - 2], ch[m - 1], pt[i])) <= 0) m--;
            ch[m++] = pt[i];
        }
        int k = m;
        for (int i = n - 2; i >= 0; i--) {
            while (m > k && sgn(crossDet(ch[m - 2], ch[m - 1], pt[i])) <= 0) m--;
            ch[m++] = pt[i];
        }
        if (n > 1) m--;
        return m;
    }
    const int N = 555;
    Point pt[N], ch[N];
    int rnd[N];
    void randPoint(Point *pt, int n) {
        for (int i = 0; i < n; i++) rnd[i] = (rand() % n + n) % n;
        for (int i = 0; i < n; i++) swap(pt[i], pt[rnd[i]]);
    }
    inline bool inCircle(Point p, Circle C) { return sgn(vecLen(C.c - p) - C.r) <= 0;}
    int main() {
        int n;
        while (cin >> n && n) {
            for (int i = 0; i < n; i++) scanf("%lf%lf", &pt[i].x, &pt[i].y);
            n = andrew(pt, n, ch);
            randPoint(ch, n);
            Circle ans = Circle(ch[0], 0.0), tmp;
            for (int i = 0; i < n; i++) {
                if (inCircle(ch[i], ans)) continue;
                ans = Circle(ch[i], 0.0);
                for (int j = 0; j < i; j++) {
                    if (inCircle(ch[j], ans)) continue;
                    ans = Circle(getMid(ch[i], ch[j]), vecLen(ch[i] - ch[j]) / 2.0);
                    for (int k = 0; k < j; k++) {
                        if (inCircle(ch[k], ans)) continue;
                        ans = getCircle(ch[i], ch[j], ch[k]);
                    }
                }
            }
            printf("%.2f
    ", ans.r + 0.5);
        }
        return 0;
    }
    
  • 相关阅读:
    A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
    Fliptile 开关问题 poj 3279
    Face The Right Way 一道不错的尺取法和标记法题目。 poj 3276
    Aggressive cows 二分不仅仅是查找
    Cable master(二分题 注意精度)
    B. Pasha and String
    Intervals poj 1201 差分约束系统
    UITextField的快速基本使用代码块
    将UIImage转换成圆形图片image
    color转成image对象
  • 原文地址:https://www.cnblogs.com/forever97/p/3650047.html
Copyright © 2011-2022 走看看