HDU 6242 Geometry Problem——随机化算法+几何

版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/82633554

随机选三个点, 选错的概率是0.5*0.5*0.5,重复次数越多出错率越低。所以无限循环直到找到解就可以了,注意特判n<=4的情况,此时一个圆只要包含两个点就可以,不用三点确定圆

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const double eps = 1e-8;
int dcmp(double x) { if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }
struct Point {
    double x, y;
    Point(double x = 0, double y = 0) : x(x), y(y) {}
}point[maxn];
struct Line { Point a, b; };
typedef Point Vector;
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
Point cal(Point a, Point b, Point c) {
    Point cp;
    double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1) / 2;
    double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2) / 2;
    double d = a1 * b2 - a2*b1;
    cp.x = a.x + (c1*b2 - c2*b1) / d;
    cp.y = a.y + (a1*c2 - a2*c1) / d;
    return cp;
}
double dis(Point a, Point b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); }
int main() {
    srand((unsigned int)time(0));
    int T, n;
    scanf("%d", &T);
    while (T--) {
        Point ans;
        double ansR;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%lf%lf", &point[i].x, &point[i].y);
        if(n == 1){
            printf("%.6f %.6f 1\n",point[1].x+1, point[1].y);
            continue;
        }
        if(n <= 4){
            double x = (point[1].x + point[2].x)/2;
            double y = (point[1].y + point[2].y)/2;
            double r = dis(point[1], point[2])/2;
            printf("%.6f %.6f %.6f\n",x,y,r);
            continue;
        }
        while (1) {
            int idx1 = rand() % n + 1, idx2 = rand() % n + 1, idx3 = rand() % n + 1;
            if (idx1 == idx2 || idx1 == idx3 || idx2 == idx3) continue;
            Point a = point[idx1], b = point[idx2], c = point[idx3];
            if (dcmp((a.y-b.y)*(b.x-c.x)-(a.x-b.x)*(b.y-c.y)) == 0) continue;
            Point center = cal(a, b, c);
            double R = dis(center, a);
            int cnt = 0;
            for (int i = 1; i <= n; i++) {
                if (dcmp(dis(point[i], center) - R) == 0) cnt++;
            }
            if (cnt >= (int)ceil(1.0*n/2)) {
                if (fabs(center.x) > 1e9 || fabs(center.y) > 1e9 || fabs(R) > 1e9) continue;
                ans = center, ansR = R;
                break;
            }
        }
        printf("%.6f %.6f %.6f\n", ans.x, ans.y, ansR);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/82633554
今日推荐