ZOJ 3550 Big Keng

_(:3」∠)_

对于任意的V,要使表面积最小,H,R,h,r会符合一定的比例关系。

然后算得 表面积=C*(V的2/3次方)   C为一常数。

故设V=1的时候算出C值。

对于R,V1(上面圆柱的体积),r而言,这个奇怪的组合体的表面积的函数都为单峰函数,然后三分R,再在里面三分V1,再在里面三分r,算出H和h的值,更新最小表面积。

//通过这个计算常数C
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#define eps 1e-9
using namespace std;

const double pi=acos(-1);

double v=1.0;
double ans=9999999;

double calr(double R2,double R1,double V1)
{
	double sum=(V1/(pi*R1*R1))*2*pi*R1;
	double V2=v-V1;
	double H=V1/(pi*R1*R1);
	double h=(3*V2)/((R1*R1+R1*R2+R2*R2)*pi);
	sum+=(R1+R2)*pi*(sqrt((R1-R2)*(R1-R2)+h*h));
	sum+=pi*R2*R2;
	ans=min(sum,ans);
	return sum;
}

double calV(double V1,double R1)
{
	double L=0,R=R1;
	double lmid,rmid;
	while((R-L)>=eps) {
		lmid=(2*L+R)/3.0;
		rmid=(L+2*R)/3.0;
		if(calr(lmid,R1,V1)<calr(rmid,R1,V1))
			R=rmid;
		else L=lmid;
	}
	return calr(lmid,R1,V1);
}

double calR(double R1)
{
	double L=0,R=v;
	double lmid,rmid;
	while((R-L)>=eps) {
		lmid=(2*L+R)/3.0;
		rmid=(L+2*R)/3.0;
		if(calV(lmid,R1)<calV(rmid,R1))
			R=rmid;
		else L=lmid;
	}
	return calV(lmid,R1);
}

int main()
{
	double L=0,R=1000000;
	double lmid,rmid;
	while((R-L)>=eps) {
		lmid=(2*L+R)/3.0;
		rmid=(L+2*R)/3.0;
		if(calR(lmid)<calR(rmid))
			R=rmid;
		else L=lmid;
	}
	printf("%.12lf
",ans);
}



//算得常数C=3.939773107886
故AC代码为:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;

int main()
{
	double hehe=3.939773107886;
	double v;
	while(cin>>v) {
		printf("%.7lf
",hehe*pow(v,2.0/3.0));
	}
}
原文地址:https://www.cnblogs.com/morimiya/p/3624469.html