【HDU】6242-Geometry Problem

今天忽然心血来潮打开牛客网尝试了一下一站到底
前四道题都是不到二十分钟切完,然后第五道来了道计算几何
我也不会啊,于是就觉得大力随机也许可行
然鹅被精度卡到崩溃

后来我才知道
保证有解,是保证你的精度误差设置到\(10^{-3}\),有解,\(10^{-5}\)没有解
【脏话】

这题直接随机三个点求外接圆就好了,看看这个圆上有几个点,期望随机十次左右吧
注意把题里说不合法的也就是绝对值大于1e9的这样的圆都给扔掉就好了

(这也许不是篇题解,只是一篇吐槽)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
    }
    while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    	out(x / 10);
    }
    putchar('0' + x % 10);
}
mt19937 rnd(20020328);
int N;
bool vis[MAXN];
int rec[10];
struct Point {
    db x,y;
    Point(db _x = 0.0,db _y = 0.0) {
        x = _x;y = _y;
    }
    friend Point operator + (const Point &a,const Point &b) {
        return Point(a.x + b.x,a.y + b.y);
    }
    friend Point operator - (const Point &a,const Point &b) {
        return Point(a.x - b.x,a.y - b.y);
    }
    friend db operator * (const Point &a,const Point &b) {
        return a.x * b.y - a.y * b.x;
    }
    friend db dot(const Point &a,const Point &b) {
        return a.x * b.x + a.y * b.y;
    }
    friend Point operator * (const Point &a,db d) {
        return Point(a.x * d,a.y * d);
    }
    db norm() {
        return sqrt(x * x + y * y);
    }
}P[MAXN];
Point a[10];
struct Line {
    Point a,b;
    Line(Point _a = Point(),Point _b = Point()) {
        a = _a;b = _b;
    }
    friend Point GetInsect(const Line &s,const Line &t) {
        db S1 = (t.a - t.b) * (s.a - t.b);
        db S2 = (t.b - t.a) * (s.b - t.a);
        return s.a + (s.b - s.a) * (S1 / (S1 + S2));
    }
};
bool dcmp(db a,db b) {
    return fabs(a - b) < 1e-3;
}

bool calc() {
    Point c;db r;
    if(dcmp((a[2] - a[0]) * (a[1] - a[0]),0)) return false;
    Point l1,l2;
    l1.x = -(a[1] - a[0]).y;l1.y = (a[1] - a[0]).x;
    l2.x = -(a[2] - a[0]).y;l2.y = (a[2] - a[0]).x;
    Line s,t;
    s.a = (a[0] + a[1]) * 0.5;s.b = s.a + l1;
    t.a = (a[0] + a[2]) * 0.5;t.b = t.a + l2;
    c = GetInsect(s,t);
    r = (a[0] - c).norm();
    if(fabs(c.x) > 1e9 || fabs(c.y) > 1e9 || r > 1e9) return false;

    int cnt = 0;
    for(int i = 1 ; i <= N ; ++i) {
        if(dcmp((P[i] - c).norm(),r)) ++cnt;
    }
    if(cnt >= (N - 1) / 2 + 1) {
        printf("%.6lf %.6lf %.6lf\n",c.x,c.y,r);
        return true;
    }
    return false;
}
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) {
        scanf("%lf%lf",&P[i].x,&P[i].y);
    }
    if(N == 1) {
        Point c(0,0);db r = (P[1] - c).norm();
        printf("%.6lf %.6lf %.6lf\n",c.x,c.y,r);
        return;
    }
    else if(N <= 4) {
        Point c = (P[1] + P[2]) * 0.5;
        db r = (P[1] - c).norm();
        printf("%.6lf %.6lf %.6lf\n",c.x,c.y,r);
        return;
    }
    memset(vis,0,sizeof(vis));
    while(1) {
        for(int i = 0 ; i < 3 ; ++i) {
            int t = (rnd() % N + N) % N + 1;
            while(vis[t])  {
                t = (rnd() % N + N) % N + 1;
            }
            a[i] = P[t];rec[i] = t;
            vis[t] = 1;
        }
        if(calc()) return;
        for(int i = 0 ; i < 3 ; ++i) vis[rec[i]] = 0;
    }

}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    srand(time(0));
    int T;
    read(T);
    while(T--) Solve();
    return 0;
}
posted @ 2019-06-07 16:35  sigongzi  阅读(291)  评论(0编辑  收藏  举报