The height of liquid level in the cup is d (0 ≤ d ≤ 2). When you incline the cup to the maximal angle such that the liquid inside has not been poured out, what is the area of the surface of the liquid?
4 0 1 2 0.424413182
0.00000 4.44288 3.14159 3.51241
題目大意:
有一個圓柱瓶子,高爲
解題思路:
二分底面,然後積分求面積和體積。
由高中學過的幾何知識可以知道:水面相當於對於一個很長的圓柱體傾斜的用刀切開,那麼這個切面就是一個完整的橢圓,當然如果不傾斜則得到特殊的橢圓——圓,如果水面經過杯底,那麼水面就是一個缺少一部分的橢圓,所以我們需要分開討論水面經過杯底和不經過杯底兩種情況。
那麼這兩種情況的d的臨界值是多少呢? 可以發現對於水剛到杯底的時候,有水和無水的部分各佔一半,所以分界點d=1;
1、水面不經過杯底
這種情況如上圖所示,
2、水面經過杯底
對於上圖中
積分:我們根據水的高度積分,如上圖所示利用
可以知道水體截面爲一個扇形減去一個三角形組成,面積及體積如下圖所示:
求出真實的
如上圖所示利用二分求出的
現在橢圓方程已求出,
代碼:
#include <iostream>
#include <string.h>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <map>
using namespace std;
typedef long long LL;
const int MAXN = 1e6+5;
const double PI = acos(-1);
const double eps = 1e-8;
const LL MOD = 1e9+7;
double cal2(double a,double x)
{
double sum=x+sin(2*x)/2;
return sum*a*0.5;
}
double area(double a,double x)
{
double sum=cal2(a,0.5*PI);
sum=sum-cal2(a,asin(x/a));
return sum*2;
}
double cal(double x)
{
double ans=sin(x)-sin(x)*sin(x)*sin(x)/3-x*cos(x);
return ans;
}
double getV(double mid)
{
double V=cal(0)-cal(acos(1-mid));
V=V*(-2)/mid;
return V;
}
int main()
{
int T; cin>>T;
while(T--)
{
double d; scanf("%lf",&d);
if(d>1)
{
double h=2*d-2;
double a=sqrt(4+(2-h)*(2-h))/2;
printf("%.5f\n",PI*a);
continue;
}
double l=0,r=2.0;
for(int i=0;i<100;i++)
{
double mid=(l+r)/2;
double V=getV(mid);
if(V-PI*d>eps) r=mid;
else l=mid;
}
double mid=l;
int flag=1;
if(mid<1) flag=-1;
double len=sqrt(mid*mid+4);
double h=sqrt(1-(1-mid)*(1-mid));
double a=len/(1+flag*sqrt(1-h*h));
double x=a-len;
double res=area(a,x);
printf("%.5f\n",res);
}
return 0;
}