题目来源:

https://vjudge.net/contest/296454#problem/F

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3733

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 requirment 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 < √3 × 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 5
300 50 2000 500 10

Sample Output

149968.308
2196020.459

题意:

给你最顶层圆的半径r和最底层远的半径R,每层楼的高度H,楼的层数F,玻璃的最小面积s,要你求出能围住每个圆的最小玻璃面积。(这个s真的理解要死人,直到刚刚队友和我说单个面积要求不能超过s,顿悟。。。。。我好菜)

思路:从下往上,圆半径按等差数列递减,不难看出,围住圆的多边形边数越多,所需的玻璃的面积就越少,所以只要求出围住每层圆的最多正多边形的边数就可以求出最后所需的最少的玻璃面积。而求出正多边形边数的方法可以二分,从3条边到100000进行查找符合最大面积不超过s的面的边数QAQ....

附上已知正多边形边数为n,内接圆半径为r,得正多边形边长的简单计算过程

如图易得边长AB=2*AC=2*tan(AOC)*r=2*tan(2*pi/2*n)*r=2*r*tan(pi/n); 

参考代码: 

#include<iostream>
#include<algorithm>
#include <iomanip>
#include <cmath>
#define N 10005
using namespace std;
const double pi=acos(-1.0);
double r,R,H,F,S,h,rr,ans,d;
double fun_C(double n,double r)//已知正多边形边数为n,内接圆半径为r,得正多边形边长
{
    return 2.0*r*tan(pi/n);
}
double check()
{
    int l=3,r=100000;
    int mid,num;
    double sum;
    while(l<=r)//二分求出多边形的最大边数==面积最小
    {
        mid=(l+r)>>1;
        double temp=fun_C(mid,rr)*h;
        if(temp-S>0)//最小面积不能超过s
        {
            sum=temp;
            num=mid;
            l=mid+1;
        }
        else
            r=mid-1;
    }
    l=num;
    return num*sum;
}
int main()
{
    while(cin>>R>>r>>H>>F>>S)
    {
        h=H/F,ans=0,d=(R-r)/F;//h==每层高度 d==从下往上圆半径减小的等差值
        for(int i=F; i>=1; i--)
        {
            rr=d*(i-1)+r;
            ans+=check();
        }
        cout<< fixed << setprecision(3) <<ans<<endl;//要是知道时间复杂度够的话一般我更喜欢c++控制的小数位数
    }
    return 0;
}