题目描述:
一个有着共同底的圆柱套一个圆台.具体的图在http://acm.bnu.edu.cn/v3/contest_show.php?cid=6413#problem/B
它的r,R,h1,h2都不知道.现在给出体积.求最小的表面积.注意是一个桶,有很多面没有.
题解:
大大大暴力的三分.三分3次. 关键是注意精度的把握.
重点:
(1)几何可以用三分做+long double做
(2)三分的边界开始的设定可能和输入有关.
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <ctype.h>
#include <limits.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#define CLR(a) memset(a, 0, sizeof(a))
#define REP(i, a, b) for(int i = a;i < b;i++)
#define REP_D(i, a, b) for(int i = a;i <= b;i++)
typedef long long ll;
using namespace std;
const double Pi = acos(-1.0);
double v;
double h ;
double calcu(double R, double r, double H)
{
double tmpv = v - Pi*R*R*H;
h = 3.0*tmpv/(Pi*(R*R+R*r+r*r));
return Pi*r*r + Pi*(R+r)*sqrt((R-r)*(R-r)+h*h) + 2.0*Pi*R*H;
}
double calu_r(double R, double H)
{
double rl = 1e-2*v, rr = R;
double mid, midmid, ansmid, ansmidmid;
while(fabs(rl-rr) > 1e-7)
{
mid = (rl + rr)/2;
midmid = (rl + mid)/2;
ansmid = calcu(R, mid, H);
ansmidmid = calcu(R, midmid,H);
if(ansmid < ansmidmid)
{
rl = midmid;
}
else
{
rr = mid;
}
}
return ansmid;
}
double solve(double H)
{
double Rl = 1e-2*v,Rr = 1e2*v;
double mid, midmid, ansmid, ansmidmid;
while(fabs(Rl-Rr) > 1e-7)
{
mid = (Rl+Rr)/2;
midmid = (mid+Rl)/2;
ansmid = calu_r(mid, H);
ansmidmid = calu_r(midmid, H);
if(ansmid < ansmidmid)
{
Rl = midmid;
}
else
{
Rr = mid;
}
}
return ansmid;
}
double calcu_H()
{
double Hl = 1e-2*v,Hr = 1e2*v;//边界和v有关.
double mid, midmid, ansmid, ansmidmid;
while(fabs(Hl-Hr) > 1e-7)
{
mid = (Hl+Hr)/2;
midmid = (mid+Hl)/2;
ansmid = solve(mid);
ansmidmid = solve(midmid);
if(ansmid < ansmidmid)
{
Hl = midmid;
}
else
{
Hr = mid;
}
}
return ansmid;
}
int main()
{
//freopen("2Bin.txt", "r", stdin);
//freopen("3Bout.txt", "w", stdout);
//printf("dsf");
while(scanf("%lf", &v) != EOF)
{
double key = calcu_H();
printf("%f\n", key);
}
return 0;
}