HDU3756
題意:給定三圍空間里面某些點,求構造出一個棱錐,將所有點包含,并且棱錐的體積最小。
輸入:
T(測試數據組數)
n(給定點的個數)
a,b,c(對應xyz坐標值)
.
.
.
輸出:
H(構造棱錐的高)
R(構造棱錐的半徑)
思路:
輸入:
T(測試數據組數)
n(給定點的個數)
a,b,c(對應xyz坐標值)
.
.
.
輸出:
H(構造棱錐的高)
R(構造棱錐的半徑)
思路:
簡單的一次求導極值問題,首先將三圍虛擬化成二維,可以這樣想,以棱錐的高為三角形的高,棱錐的里面半徑為三角形的底邊,所以可以理解為要求棱錐的最小體積,即V=π*H*R^r/3最小,在虛擬的二維三角形里面,斜邊長你可以假設其中的某個點為(a,b),斜率為k,那么斜邊方程就知道,利用x=0,y=0兩個特殊值,可以解出H和R,代入V里面,求一階導,得出 -π*(aK^2+2bK)*(aK-b)^2?/K^2 ,所以利用單調性可以判斷K=-2b/a時有極值,然后利用三分求極值枚舉R,給個三分求極值的解釋我是鏈接? ,之后求出最小的H即可。
#include <stdio.h> #include <math.h> #include <iostream> using namespace std;#define PI acos(-1.0)struct P {double x;double y;double z;double r; };P point[10001]; int n; double r,z,ans;double cal(double R) {int i;double max = 0;for(i = 0; i < n; i ++){double nz = point[i].z/(R - point[i].r);if(max < nz)max = nz;}return max * R; }double ss()//三分枚舉確定極值 {double right = 2*1e4, left = r, ml, mr;while(right - left > 1e-4){ml = (right + 2*left)/3.0;mr = (left + 2*right)/3.0;double lans = cal(ml)*ml*ml;double rans = cal(mr)*mr*mr;if(lans < rans)right = mr;else left = ml;}ans = (right + left)/2.0;//cout<<ans<<endl;return ans; }int main() {int t;int i,j;scanf("%d",&t);while(t--){scanf("%d",&n);r = z = 0;for(i = 0; i < n; i ++){scanf("%lf%lf%lf",&point[i].x,&point[i].y,&point[i].z);point[i].r = sqrt(point[i].x * point[i].x + point[i].y * point[i].y);if(r < point[i].r)r = point[i].r;if(z < point[i].z)z = point[i].z;}double flag = ss();printf("%.3lf %.3lf\n",cal(flag),flag);}return 0; }
轉載于:https://www.cnblogs.com/yefengCrazy/p/5636715.html
總結
- 上一篇: Java 并发:Executor Exe
- 下一篇: 存货资产周转率的正常范围(资产管理比率中