UVA 3485 Bridge

题目大意

你的任务是修建一座大桥。桥上等距地摆放着若干个塔,塔高为H,宽度忽略不计。相邻两座塔之间的距离不能超过D。塔之间的绳索形成全等的对称抛物线。桥长度为B,绳索总长为L,如下图所示求建最少的塔时绳索的最下端离地的高度y。

UVA 3485 Bridge

【输入格式】
输入第一行为测试数据组数T。每组数据包含4个整数D,H,B,L(B<=L)。

【输出格式】
对于每组数据,输出绳索底部离地高度,保留两位小数。

间隔数为n=[(B+D-1)/D],所以间隔和每个间隔的绳子长分别为w=B/n,L=L/n

根据微积分,一个二次函数的弧长len=∫√(1+[f'(x)]2)

不懂看https://wenku.baidu.com/view/7c3f0a8a02d276a200292e12.html

因为要确定y=kx2的k,找到可以使len=L的k,len的计算用辛普森

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 }