用C++暴力求出正方體中放置的最大正方形
前些天女朋友無聊刷知乎,刷到一個有趣的問題,拿這個來考我。本人數學不算好,但是儘力嘗試,算了許久都沒有算出來。但是作為一個計算機專業的大一寶寶,為什麼不能藉此機會體會一下暴力的美感呢。
原問題如下:
體積為1的正方體內,能放進的最大正方形面積是多少? @謝大大
首先,面積最大的正方形一定經過正方體的體心。
令最大的正方形為然後,設其中一條對角線的一半為 ,在正方體上找到這一條線段:
則向量 為
,設過
點平面
,則
為
,接著我們找出
平面與
三個平面的交線。將
代入
,得到
。
#define STEP 0.001#define EPSILON 1e-5double dis(double a,double b,double c){ return sqrt(a*a+b*b+c*c);}double x_brane(double m,double n){ double re=0.0; double y; for(double z=-0.5;z<=0.5+EPSILON;z+=STEP) { y=-(z+m)/n/2.0; if(abs(y)<=0.5) { double t=dis(0.5,y,z); if(t>re) re=t; } } return re;}
同理求出 與其他兩個平面交線上離中心最遠的距離。
double y_brane(double m,double n){ double re=0.0; double z; for(double x=-0.5;x<=0.5+EPSILON;x+=STEP) { z=-2.0*m*x-n; if(abs(z)<=0.5) { double t=dis(x,0.5,z); if(t>re) re=t; } } return re;}double z_brane(double m,double n){ double re=0.0; double y; for(double x=-0.5;x<=0.5+EPSILON;x+=STEP) { y=-(m*x+0.25)/n; if(abs(y)<=0.5) { double t=dis(x,y,0.5); if(t>re) re=t; } } return re;}
得到三條交線離中心點最大的距離之後,在 與這個最大距離當中取最小值,得到的就是正方形對角線長度的一半,由此可求出正方形的面積。
int main(int argc, const char * argv[]) { double m=0,n=0; double ans=0; double ansm=0,ansn=0; for(m=0;m<=0.5+EPSILON;m+=STEP) for(n=0;n<=0.5+EPSILON;n+=STEP) { double this_egde=dis(m,n,0.5); double z=z_brane(m,n),x=x_brane(m,n),y=y_brane(m,n); printf("m=%.3lf, n=%.3lf, ",m,n); printf("x=%.3lf, y=%.3lf, z=%.3lf,",x,y,z); double max_edge=max(x,max(y,z)); printf(" s=%.3lf
",min(this_egde,max_edge)); if(ans { ans=min(this_egde,max_edge); ansm=m;ansn=n; } } cout<<ans<<" "<<(ans*ans)*2<<endl; printf("( %.3lf , %.3lf , %.3lf )
",ansm,ansn,0.5); return 0;}
最終結果:能放進的最大正方形面積為 1.125
各個頂點都在某條棱的1/4處,具體請看題圖。本人學寫程序不久,水平有限,有錯誤或不足之處煩請各位大神指出,謝謝!
推薦閱讀: