题意:给你最顶层圆的半径r和最底层远的半径R,每层楼的高度H,楼的层数f,玻璃的最小面积s,要你求出能围住每个圆的最小玻璃面积。
一开始没看懂题意,就试着将圆的半径按等差数列递减,没想到居然对了。
推理可以得出,围住圆的多边形边数越多,所需的玻璃的面积就越少,所以只要求出围住每层圆的最多正多边形的边数就可以求出最后所需的最少的玻璃面积。而求出正多变形的方法,我用的和第一道题一样的方法,二分查找,从3条边到100000进行查找,最后就可以得出,而且玻璃的面积要大于s。
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<bitset>
#include<vector>
#include<cmath>
using namespace std;
const double pi=acos(-1.0);
int r,R,h,f,s;
double caldis(int n,double r)
{
return 2.0*r*tan(pi/n);
}
int main()
{
int i,j,k;
while(scanf("%d%d%d%d%d",&R,&r,&h,&f,&s)!=EOF)
{
double sh=(double)h/f;
double ans=0;
int larn=100000;
for(i=f;i>=1;i--)
{
double rr=1.0*(R-r)/f*(i-1)+r;
int minn=3,maxx=larn;
int mid,num;
double ss;
while(minn<=maxx)//二分求出多边形的最多边数
{
mid=(minn+maxx)>>1;
double tmp=caldis(mid,rr)*sh;
if(tmp-s>0)//最小面积要大于s
{
ss=tmp;
num=mid;
minn=mid+1;
}
else
maxx=mid-1;
}
ans+=num*ss;
larn=num;
}
printf("%.3lf\n",ans);
}
}