传送门:https://ac.nowcoder.com/acm/contest/12606#question

 

A题 Weird Flecks, But OK

题解:计算几何 最小圆覆盖问题

B题 Code Names

题解:建图+匈牙利算法   最大团=补图的最大独立集  最大独立集=点数-最大匹配/2

C题 New Maths

题解:搜索

D Some Sum

题解:签到题  暴力

E Early Orders

题解:栈模拟

F Pulling Their Weight

题解:签到题

G Birthday Paradox

题解:组合数学

H On Average They're Purple

题解:最短路

J This Ain't Your Grandpa's Checkerboard

题解:模拟

 

A把点投到三个平面,做三次最小点覆盖。 

#include<bits/stdc++.h>
using namespace std;

#define N 5210
#define pf(x) ((x)*(x))
#define eps 1e-6
int n;
double x[N],y[N],z[N];
double R;
struct point
{
    double x,y;
}p[N],O;
//求两点间的距离 
double getdis(point a,point b)
{
    return sqrt(pf(a.x-b.x)+pf(a.y-b.y));
}
//三点定一圆的圆心 
point getO(point p1,point p2,point p3)
{
    point res; 
    double a=p2.x-p1.x;
    double b=p2.y-p1.y;
    double c=p3.x-p2.x;
    double d=p3.y-p2.y;
    double e=pf(p2.x)+pf(p2.y)-pf(p1.x)-pf(p1.y);
    double f=pf(p3.x)+pf(p3.y)-pf(p2.x)-pf(p2.y);
    res.x=(f*b-e*d)/(c*b-a*d)/2.0; 
    res.y=(a*f-e*c)/(a*d-b*c)/2.0; 
    return res; 
}

void slove()
{
    O=p[1];R=0;
    for(int i=1;i<=n;i++)
    {
        if(getdis(p[i],O)-R>eps)
        {
            O=p[i];R=0;
            for(int j=1;j<i;j++)
            {
                if(getdis(p[j],O)-R>eps)
                {
                    O=(point){(p[i].x+p[j].x)/2.0,(p[i].y+p[j].y)/2.0};
                    R=getdis(p[i],p[j])/2.0;
                    for(int k=1;k<j;k++)
                    {
                        if(getdis(p[k],O)-R>eps)
                        {
                            O=getO(p[i],p[j],p[k]);
                            R=getdis(p[i],O);
                        }
                    }
                }
            }
        }
    }
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>x[i]>>y[i]>>z[i];
    double ans=100000;
    for(int i=1;i<=n;i++) p[i].x=x[i],p[i].y=y[i];
    random_shuffle(p+1,p+1+n);
    slove();
    if(ans-R>eps) ans=R;
    for(int i=1;i<=n;i++) p[i].x=x[i],p[i].y=z[i];
    random_shuffle(p+1,p+1+n);
    slove();
    if(ans-R>eps) ans=R;
    for(int i=1;i<=n;i++) p[i].x=y[i],p[i].y=z[i];
    random_shuffle(p+1,p+1+n);
    slove();
    if(ans-R>eps) ans=R;
    printf("%.10f",2*ans);
}
View Code

相关文章: