HDU 3756 還是三分
阿新 • • 發佈:2019-01-22
這題雖然是三維空間,但完全可以轉換到一個平面XZ考慮,Z軸不變,X軸是 根號下X*X+Y*Y
問題等價於求最小的三角形覆蓋平面上所有的點,必然至少有一點在斜邊上
設斜邊的斜率為K,一點為(a,b)
則斜邊方程為 y=k*(x-a)+b;
h=-a*k+b;
r=-b/k+a;
得到體積的方程,並證明是是凸性,有最小值
這時候我們就可以通過三分列舉一個變數,計算得到一個最小的另一個變數
假設H已知, 則R=a*h/(b-h) 最終求得答案
#include<math.h> #include<string.h> #include<stdio.h> #define eps 1e-8 #define maxn 10010 struct point { double x,z; }p[maxn]; int n; double maxx(double a,double b) { return a>b?a:b; } double getR(double h) { double r=0.0; int i; for(i=0;i<n;i++) r=maxx(r,p[i].x*h/(h-p[i].z)); return r; } int main() { while( scanf("%d",&n)==1) { double x,y,z; double h0=0.0; int i,j; for(i=0;i<n;i++) { scanf("%lf%lf%lf",&x,&y,&z); p[i].x=sqrt(x*x+y*y); p[i].z=z; h0=maxx(h0,p[i].z); } double l=h0+eps,r=1e6,mid,midmid; while(r-l>eps) { mid=(l+r)/2.0; midmid=(mid+r)/2.0; double r1=getR(mid); double r2=getR(midmid); if(r1*r1*mid<r2*r2*midmid) r=midmid; else l=mid; } printf("%.3lf %.3lf\n",l,getR(l)); } return 0; }