<span>AtCoder Beginner Contest 151 *F - Enclose All* (最小圆覆盖)</span>

AtCoder Beginner Contest 151 -F - Enclose All (最小圆覆盖)

Problem Statement

Given are NN points (xi,yi)(xi,yi) in a two-dimensional plane.

Find the minimum radius of a circle such that all the points are inside or on it.

Constraints

  • 2≤N≤502≤N≤50
  • 0≤xi≤10000≤xi≤1000
  • 0≤yi≤10000≤yi≤1000
  • The given NN points are all different.
  • The values in input are all integers.

Input

Input is given from Standard Input in the following format:

NN
x1x1 y1y1
::
xNxN yNyN

Output

Print the minimum radius of a circle such that all the NN points are inside or on it.

Your output will be considered correct if the absolute or relative error from our answer is at most 10−610−6.


Sample Input 1 Copy

Copy

2
0 0
1 0

Sample Output 1 Copy

Copy

0.500000000000000000

Both points are contained in the circle centered at (0.5,0)(0.5,0) with a radius of 0.50.5.

思路:

最小圆低配版,可以先去学习下这题:https://www.luogu.com.cn/problem/P1742

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <ctime>
#include <random>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int n;
typedef double ld;
struct Point
{
    double x, y;
    Point() {}
    Point(double _x, double _y)
    {
        x = _x; y = _y;
    }
    Point operator +(const Point &b)const
    {
        return Point(x + b.x, y + b.y);
    }
    Point operator -(const Point &b)const
    {
        return Point(x - b.x, y - b.y);
    }
    //虏忙禄媒
    double operator ^(const Point &b)const
    {
        return x * b.y - y * b.x;
    }
    Point operator *(const double &b)const
    {
        return Point(x * b , y * b);
    }
    //碌茫禄媒
    double operator *(const Point &b)const
    {
        return x * b.x + y * b.y;
    }
    //脠脝脭颅碌茫脨媒脳陋陆脟露脠B拢篓禄隆露脠脰碌拢漏拢卢潞贸x,y碌脛卤盲禄炉
    void transXY(double B)
    {
        double tx = x, ty = y;
        x = tx * cos(B) - ty * sin(B);
        y = tx * sin(B) + ty * cos(B);
    }
    ld distance(Point bb)
    {
        // chu(sqrtl((x - bb.x) * (x - bb.x) + (y - bb.y) * (y - bb.y)));
        return sqrt((x - bb.x) * (x - bb.x) + (y - bb.y) * (y - bb.y));
    }
    void show()
    {
        cout << fixed << setprecision(6) << x << "," << y << endl;
    }
};
Point a[maxn];
struct Circle
{
    Point center;
    double  r;
    Circle() {}
    Circle(Point c1, double r1) {
        center = c1;
        r = r1;
    }
};
Circle makeCircumcircle( Point &a,  Point &b,  Point &c) {
    // Mathematical algorithm from Wikipedia: Circumscribed circle
    if ( fabs((a - b) ^ (a - c)) < eps) {
        return Circle(a, 1e9);// (a,b)//(a,c)
    }
    double ox = (min(min(a.x, b.x), c.x) + max(min(a.x, b.x), c.x)) / 2;
    double oy = (min(min(a.y, b.y), c.y) + max(min(a.y, b.y), c.y)) / 2;
    double ax = a.x - ox,  ay = a.y - oy;
    double bx = b.x - ox,  by = b.y - oy;
    double cx = c.x - ox,  cy = c.y - oy;
    double d = (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) * 2;
    if (fabs(d) < eps)
        return Circle(a, 1e9);//
    double x = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d;
    double y = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d;
    Point p(ox + x, oy + y);
    double r = max(max(p.distance(a), p.distance(b)), p.distance(c));
    // chu(r);
    return Circle(p, r);
}

int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    gbtb;
    cin >> n;
    repd(i, 1, n)
    {
        cin >> a[i].x >> a[i].y;
    }
    mt19937 rnd(time(0));
    shuffle(a + 1, a + 1 + n, rnd);
    Circle res = Circle(a[1], 0.0);
    repd(i, 1, n)
    {
        if (res.center.distance(a[i]) > res.r)
        {
            res = Circle(a[i], 0.0);
            repd(j, 1, i - 1)
            {
                if (res.center.distance(a[j]) > res.r)
                {
                    res = Circle((a[i] + a[j]) * 0.5, a[i].distance(a[j]) * 0.5);
                    repd(k, 1, j - 1)
                    {
                        if (res.center.distance(a[k]) > res.r)
                        {
                            res = makeCircumcircle(a[i], a[j], a[k]);
                        }
                    }
                }
            }
        }
    }
    cout << fixed << setprecision(10) << res.r << endl;
    return 0;
}



全部评论

相关推荐

下北泽:都是校友,还是同届,我就说直白点,不委婉了,我相信你应该也不是个玻璃心,首先你觉得一个双非的绩点写简历上有用吗?班长职务有用吗?ccf有用吗?企业会关心你高数满分与否吗?第二,第一个项目实在太烂,一眼就能看出是外卖,还是毫无包装的外卖,使用JWT来鉴权,把热点数据放进Redis这两个点居然还能写进简历里,说难听点这两个东西都是学个几十分钟,调用个API就能完成的事情,在双非一本的条件下,这种项目你觉得能拿出手吗,第二个项目你写的东西和你的求职方向有任何的匹配吗?第三,计设那一块毫无价值,如果想突出自己会前端,直接写入专业技能不行吗,最后,专业技能里像深入理解JVM底层原理这种你觉得这句话你自己真的能匹配吗?都是校友加上同届,我措辞直接,但希望能点出你的问题,想进大厂还得继续沉淀项目和学习
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务