传送门: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); }