码迷,mamicode.com
首页 > 其他好文 > 详细

例题2.28 桥上的绳索 UVa1356

时间:2015-03-17 14:16:13      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:二分法   数值问题   

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;
}



例题2.28 桥上的绳索 UVa1356

标签:二分法   数值问题   

原文地址:http://blog.csdn.net/u014800748/article/details/44340351

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!