1.题目描述:点击打开链接
2.解题思路:本题算是一道微积分题目,首先根据题目条件列写方程:间隔数n=ceil(B/D),每个间隔宽度D1=B/n,每段绳索长度L1=L/n。接下来就是根据D1,L1来计算底部离地面的高度y了。不过我们会发现,这个方程很难找到求解公式,因此应该转移思路,试图利用数值问题中的二分法逐渐逼近这个高度值。设函数P(w,h)计算出来抛物线的长度,其中w表示抛物线开口的宽度,h表示抛物线的高度,那么不难发现,这个函数是一个单调函数:当w固定时,它随着h的增大而增大。由于抛物线长度也是确定的,因此此时可以通过二分法求解高度h。
那么,该如何计算P(w,h)这个函数呢,我们可以利用微积分中的弧长公式来计算弧长,同时可以查表求出这个弧长公式的原函数,从而求得弧长,具体过程略去。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; typedef long long LL; double F(double a, double x)//求sqrt(a^2+x^2)的原函数 { double a2 = a*a, x2 = x*x; return (x*sqrt(a2 + x2) + a2*log(fabs(x + sqrt(a2 + x2))))/2; } double P(double w, double h)//求弧长 { double a = 4.0*h / w / w; double b = 1.0 / 2 / a; return (F(b, w / 2) - F(b, 0)) * 4 * a; } int main() { freopen("t.txt", "r", stdin); int T; cin >> T; for (int rnd = 1; rnd <= T; rnd++) { int d, h, b, l; cin >> 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; while (y - x > 1e-5)//利用二分法求解高度h { double m = x + (y - x) / 2; if (P(d1, m) < l1)x = m; else y = m; } if (rnd>1)cout << endl; printf("Case %d:\n%.2lf\n", rnd, h - x); } return 0; }
原文地址:http://blog.csdn.net/u014800748/article/details/44340351