很容易就想到把三维转化成了二维,求出点离Z轴的距离,把这个距离当成X坐标,Z轴当Y坐标,然后就变成了求一个直角三角形覆盖这些点
像上一题一样,确定斜率直线的时候,必定是有一点在线上的。于是,可以把直线看成垂直X轴,按角度旋转点即可。
也有二分高度的做法。
#include <iostream> #include <cmath> #include <cstdio> #include <algorithm> using namespace std; struct Point{ double x,y; }; Point point[10050]; int n; const double PI=3.141592653; const double inf=1e10; double ansx,ansh; double cal(double ang){ double cs=cos(ang),sn=sin(ang); double x; double xmax=-inf; for(int i=1;i<=n;i++){ x=cs*point[i].x-sn*point[i].y; xmax=max(xmax,x); } ang=-ang; cs=cos(ang),sn=sin(ang); ansx=xmax/cs; ansh=xmax/sn; return ansx*ansx*PI*ansh/3; } int main(){ int T;double x,y,z; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lf%lf%lf",&x,&y,&z); point[i].y=z; point[i].x=sqrt(x*x+y*y); } double l=-90*PI/180,r=0; double m,mm; while(l+(1e-8)<r){ m=l+(r-l)/3; mm=r-(r-l)/3; if(cal(m)>cal(mm)) l=m; else r=mm; } cal(l); printf("%.3lf %.3lf ",ansh,ansx); } return 0; }