题目大意
你的任务是修建一座大桥。桥上等距地摆放着若干个塔,塔高为H,宽度忽略不计。相邻两座塔之间的距离不能超过D。塔之间的绳索形成全等的对称抛物线。桥长度为B,绳索总长为L,如下图所示求建最少的塔时绳索的最下端离地的高度y。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CM0UGNzQmY3YjN1UGOhZjM3QjYmFmMlFWY3QWNmJGNw8CX4AzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL0M3Lc9CX6MHc0RHaiojIsJye.png)
【输入格式】
输入第一行为测试数据组数T。每组数据包含4个整数D,H,B,L(B<=L)。
【输出格式】
对于每组数据,输出绳索底部离地高度,保留两位小数。
间隔数为n=[(B+D-1)/D],所以间隔和每个间隔的绳子长分别为w=B/n,L=L/n
根据微积分,一个二次函数的弧长len=∫√(1+[f'(x)]2)
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<cmath>
6 using namespace std;
7 double k,D,H,B,L,eps=1e-5,ans,Eps=1e-5;
8 double F(double X)
9 {
10 return sqrt(1+4.0*k*k*X*X);
11 }
12 double simpson(double l,double r)
13 {
14 return (r-l)*(F(l)+F(r)+4.0*F((l+r)/2.0))/6.0;
15 }
16 double asr(double l,double r,double eps,double A)
17 {
18 double mid=(l+r)/2.0;
19 double LS=simpson(l,mid),RS=simpson(mid,r);
20 if (fabs(LS+RS-A)<=15.0*eps) return LS+RS+(LS+RS-A)/15.0;
21 return asr(l,mid,eps/2.0,LS)+asr(mid,r,eps/2.0,RS);
22 }
23 int main()
24 {int T,t,cnt;
25 double w;
26 cin>>T;
27 while (T--)
28 {
29 scanf("%lf%lf%lf%lf",&D,&H,&B,&L);
30 int n=(B+D-1)/D;
31 w=B/(double)n;
32 L=L/(double)n;
33 double l=0,r=H;
34 while (l+Eps<r)
35 {
36 double mid=(l+r)/2.0;
37 k=4.0*mid/(w*w);
38 if (2.0*asr(0,w/2.0,eps,simpson(0,w/2.0))-L<Eps) ans=mid,l=mid;
39 else r=mid;
40 }
41 cnt++;
42 if (cnt>1) printf("\n");
43 printf("Case %d:\n%.2lf\n",cnt,H-ans);
44 }
45 }