【题解】
首先求出分出的最少区间数:n=ceil(B/D),ceil():向上取整
然后依据每一段的宽度w=B/n及弧长L/=n来求"深度"h即可,答案为:y=H-h
w,h可确定一条抛物线,其弧长L关于h单调递增,考虑二分h,验证弧长
设抛物线顶点为原点,由(w/2,d)在抛物线上可知其方程为:y=a*x^2,其中a=4*h/(w*w)
可导函数f(x)在区间[a,b]上的弧长:有公式(无法打出来),可以用微元法来推导,公式中的积分部分用自适应Simpson公式来求
【代码】
#include<stdio.h> #include<stdlib.h> #include<math.h> double w,h,_a;//_a:设 F(x)=_a*x^2 double F(double x) { return sqrt(1+4*_a*_a*x*x); } double simpson(double a,double b)//三点simpson法 { double c=(a+b)/2; return (b-a)/6*(F(a)+4*F(c)+F(b)); } double asr(double a,double b,double eps,double A)//递归过程 { double c=(a+b)/2,L=simpson(a,c),R=simpson(c,b); if(fabs(L+R-A)<=15*eps) return L+R+(L+R-A)/15; return asr(a,c,eps/2,L)+asr(c,b,eps/2,R); } int main() { double H,L,left,right; int T,D,B,n,i; scanf("%d",&T); for(i=1;i<=T;i++) { scanf("%d%lf%d%lf",&D,&H,&B,&L); n=(B+D-1)/D;//平均分成的段数 L/=(double)n;//每段绳索长 w=(double)B/(double)n;//每段宽度 left=0; right=H; while(right-left>1e-4)//二分桥的"深度"h==H-y { h=(left+right)/2; _a=4*h/(w*w); if(2*asr(0,w/2,1e-4,simpson(0,w/2))<=L) left=h; else right=h; } if(i>1) printf("\n"); printf("Case %d:\n%.2lf\n",i,H-h); } return 0; }