HDU 4798 Skycity(计算几何)

来源:互联网 发布:知乎mac 编辑:程序博客网 时间:2024/06/09 14:57

Skycity

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 721    Accepted Submission(s): 283


Problem Description
The world's new tallest building is going to be built in Changsha, which will be called as "Skycity". The Skycity is going to be built as a circular truncated cone, radius of its bottom is marked as R, and radius of its top is marked as r, height of the building is marked as H, and there will be F floors with exact the same height in the whole building.
After construction of the building's skeleton, the construction team is going to construct the curtain wall using thousands of glass panes. The curtain wall is installed in each floor. When installing the curtain wall in a floor, first the construction team will measure the radius r' of the ceiling, then they will install the glass curtain wall as a regular prism which can exactly contain the ceiling circle. When constructing the glass curtain wall, all the glass pane has a minimum area requirement S, and amount of glass usage should be as little as possible.

As all the glass has exact the same thickness, so we can calculate the consumption of each glass pane as its area. Could you calculate the minimum total glass consumption?
 

Input
There will be multiple test cases. In each test case, there will be 5 integers R, r (10 ≤ r < R ≤ 10000), H (100 ≤ H ≤ 10000), F (10 ≤ F ≤ 1000) and S (1 ≤ S <× r × H ÷ F) in one line.
 

Output
For each test case, please output the minimum total glass consumption, an absolute error not more than 1e-3 is acceptable.
 

Sample Input
50 10 800 120 5300 50 2000 500 10
 

Sample Output
149968.3082196020.459
 

题意

给你如图所示的最上层的圆的半径r和最下层的R,总层数F,总高度H,最小玻璃面积S,玻璃为矩形,要求将每一层的圆柱围起来,形成一个外接正多边形,要求出这样围所用的最小玻璃总面积

思路

因为这个建筑的高度和层数已经固定,所以每一层的高度都一样是固定的,而且每一层圆柱的半径也是递增(从上往下),所以我们直接把这个立体问题转化为一个平面问题:要求一个圆的外接正多边形周长尽量小
因为玻璃的最小面积为S且每一层的高度h也固定,所以正多边形的最小长度也是固定的,我们又知道对于的一个圆来说多边形的边数越多,周长越小,那么有一个最小长度我们可不可以直接以这个最小长度来当多边形的边呢答案是不行的,因为每一层的圆不同,而最小长度所构成的正多边形是固定的所以不行,那我们怎么求某一层的多边形的边长呢
假设某一层的圆的半径为rr,那我们首先要确定这一层的圆的外接正多边形的为几边形我们可以在最小长度的基础上用取整的方法求出外接正多边形的边数n,n=(int)PI/atan(s/h/2/rr),边数就是先求出如图的小三角形的角度,然后用π来除即可,强制转化一下就是比最小长度稍大的长度的正多边形的边数了,有了边数n,那么我们可以反过来求多边形的边长,d=2*rr*tan(PI/n)
#include <iostream>#include <cstdio>#include <cstring>#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <math.h>using namespace std;const double PI=acos(-1);int main(){    double R,r,H,s;    int f;    while(scanf("%lf%lf%lf%d%lf",&R,&r,&H,&f,&s)!=EOF)    {        double h=H/f;        double ans=0;        for(int i=0;i<f;i++)        {            double rr=r+(R-r)/f*i;            int n=PI/atan(s/2/h/rr);            ans+=2*rr*tan(PI/n)*n*h;        }        printf("%.3lf\n",ans);    }    return 0;}