2018 ACM-ICPC 南京站 D Country Meow 最小球覆蓋(模擬退火&三分)
阿新 • • 發佈:2018-12-24
//模擬退火 #include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const double eps=1e-7; struct point3D { double x,y,z; } data[105]; int n; double dis(point3D a,point3D b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)); } double solve() { double step=1000,ans=1e30,mt; point3D z; z.x=z.y=z.z=0; int s=0; while(step>eps) { for(int i=0; i<n; i++) if(dis(z,data[s])<dis(z,data[i])) s=i; mt=dis(z,data[s]); ans=min(ans,mt); z.x+=(data[s].x-z.x)/mt*step; z.y+=(data[s].y-z.y)/mt*step; z.z+=(data[s].z-z.z)/mt*step; step*=0.98; } return ans; } int main() { double ans; while(scanf("%d",&n)!=EOF) { for(int i=0; i<n; i++) scanf("%lf%lf%lf",&data[i].x,&data[i].y,&data[i].z); ans=solve(); printf("%.7f\n",ans); } return 0; }
//三分 #include<bits/stdc++.h> using namespace std; const int maxn=1e2+5; const double eps=1e-7; typedef struct {double p[3];}point; point a[maxn]; int n; double cal(point now) { double ans=0.0; for(int i=0;i<n;i++) ans=max(ans,sqrt((a[i].p[0]-now.p[0])*(a[i].p[0]-now.p[0])+(a[i].p[1]-now.p[1])*(a[i].p[1]-now.p[1])+(a[i].p[2]-now.p[2])*(a[i].p[2]-now.p[2]))); return ans; } point del(point now,int cnt) { if(cnt>=3) return now; double r=100000,l=-100000; double dr,dl; point tp1,tp2,ans1,ans2,ans; tp1=tp2=ans=now; while(r-l>eps) { dr=(2*r+l)/3; dl=(2*l+r)/3; tp1.p[cnt]=dl; tp2.p[cnt]=dr; ans1=del(tp1,cnt+1); ans2=del(tp2,cnt+1); if(cal(ans1)>cal(ans2)) { l=dl; ans=ans1; } else { r=dr; ans=ans2; } } return ans; } int main() { while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) scanf("%lf%lf%lf",&a[i].p[0],&a[i].p[1],&a[i].p[2]); point ans; printf("%lf\n",cal(del(ans,0))); } return 0; } /* 3 0 0 0 3 0 0 0 4 0 4 0 0 0 1 0 0 0 1 0 0 0 1 5 0 1 2 2 3 4 5 6 7 7 8 9 9 2 3 */