#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//对积分sqrt(a^2+x^2)的求解
double fun(double a,double x)
{
double aa=a*a,xx=x*x;
return (x*sqrt(aa+xx)+aa*log(fabs(x+sqrt(aa+xx))))/2;
}
//求宽w,高h的抛物线弧长
double parabola(double w,double h)
{
double a=4.0*h/(w*w);
double b=1.0/(2*a);
return (fun(b,w/2)-fun(b,0))*4*a;
}
int main()
{
int T,tt=0;
scanf("%d",&T);
while(T--)
{
int d,h,b,l;
scanf("%d%d%d%d",&d,&h,&b,&l);
int n=(b+d-1)/d;//间隔数
double d1=(double)b/n;
double l1=(double)l/n;
double x=0,y=h;
//弧长随h单调递增,所以用二分法求得h
while(y-x>1e-5)
{
double m=(x+y)/2;
if(parabola(d1,m)<l1)x=m;
else y=m;
}
if(tt!=0)
printf("\n");
printf("Case %d:\n%.2lf\n",++tt,h-x);
}
return 0;
}
/*
纯粹的数学积分题,高数不行啊,寒一个。。。。
建立抛物线公式f(x)=a*x^2,其中a=4*h/(w*w);
有积分中的弧长公式2∫(0,w/2)√(1+(f'(x))^2)dx=2∫(0,w/2)√(1+4*a^2*x^2)^2)dx
=4a∫(0,w/2)√((1/(2*a))^2+x^2)dx
再由积分表公式∫√(a^2+x^2)dx=1/2*x*sqrt(a^2+x^2)+1/2*a*a*log(fabs(x+sqrt(a*a+x*x)))+C求得弧长
最后二分高度,求得答案
*/
UVA 1356/ ZOJ 2614 Bridge 弧长积分+二分
最新推荐文章于 2021-11-27 22:21:31 发布