桥的间隔数为n = ceil(B/D),每段绳子的长度为L / n,相邻两塔之间的距离为 B / n
主要问题还是在于已知抛物线的开口宽度w 和 抛物线的高度h 求抛物线的长度
弧长积分公式为:
设抛物线方程为f(x) = ax2,则这段抛物线弧长为
查积分表或者自己分部积分算一下:
二分抛物线高度x,使得每段抛物线长度为L / n,所求答案为H - x
1 #include <cstdio> 2 #include <cmath> 3 4 inline double F(double a, double x) 5 {//sqrt(a^2+x^2)的原函数 6 double a2 = a*a, x2 = x*x; 7 double s = sqrt(a2+x2); 8 return (x*s + a2*log(x+s))/2; 9 } 10 11 double length(double w, double h) 12 {//宽为w,高为h的抛物线的长度 13 double a = 4*h/w/w; 14 double b = 0.5/a; 15 return 4*a*(F(b, w/2) - F(b, 0)); 16 } 17 18 int main() 19 { 20 //freopen("in.txt", "r", stdin); 21 22 int T; 23 scanf("%d", &T); 24 for(int kase = 1; kase <= T; kase++) 25 { 26 int D, H, B, L; 27 scanf("%d%d%d%d", &D, &H, &B, &L); 28 int n = (B-1)/D + 1; //间隔数 29 double d = (double)B / n; //间隔 30 double l = (double)L / n; //每段绳长 31 double Left = 0, Right = H; 32 while(Right - Left > 1e-5) 33 {//二分求抛物线高度 34 double mid = (Right + Left) / 2; 35 if(length(d, mid) > l) Right = mid; 36 else Left = mid; 37 } 38 if(kase > 1) puts(""); 39 printf("Case %d:\n%.2f\n", kase, H-Left); 40 } 41 42 return 0; 43 }
代码君
时间: 2024-10-10 12:53:18