UVA1356 Bridge

空得较多的数学公式那里有一个根号,不知道为什么显示不出来
题目链接:https://www.luogu.com.cn/problem/UVA1356

题目表面意思很简单。
首先我们可以很轻易地求出抛物线的个数 c n t cnt cnt
然后可以得到每个抛物线的最长长度 l e n len len
设抛物线顶点到最高点高度为 h h h

接着需要一个引理:
可导函数 f ( x ) f(x) f(x)定义在 ( c , d ) (c,d) (c,d)上, 平面直角坐标系上[a,b]上的弧长为 ∫ a b 1 + [ f ′ ( x ) ] 2 d x \int_a^b\sqrt{1+[f'(x)]^2}dx ab1+[f(x)]2 dx

证明:令 S ( t ) S(t) S(t) c c c t t t的弧长
则: d s = lim ⁡ Δ t →   0 S ( t + Δ t ) − S ( t ) = Δ t 2 + [ f ( t + Δ t ) − f ( t ) ] 2 ds=\lim_{\Delta t \to \ 0}S(t+\Delta t)-S(t)=\sqrt{{\Delta t}^2+[f(t+\Delta t)-f(t)]^2} ds=Δt 0limS(t+Δt)S(t)=Δt2+[f(t+Δt)f(t)]2
通俗的说就是当变化量趋近于 0 0 0时弧长趋近于位移
这样我们就可以用微分推出导数: s ′ ( x ) = 1 + [ f ′ ( x ) ] 2 s'(x)=\sqrt{1+[f'(x)]^2} s(x)=1+[f(x)]2
至于求 s ( x ) s(x) s(x)积个分就好了

然后对于抛物线的高度,我们可以列出二次函数表达式 f ( x ) = 4 h l e n 2 x 2 f(x)=\frac{4h}{len^2}x^2 f(x)=len24hx2
发现 f ′ ( x ) f'(x) f(x)关于 h h h单调递增
二分求解,再用自适应自适应辛普森积分求积分即可
自适应辛普森积分(my blog)

C o d e Code Code

#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-6;
double a, len;
inline int read();
double get_ans(double);
inline double f(double);
inline double simpson(double, double);
double asr(double, double, double, double);

int main(){
	//freopen ("std.in","r",stdin);
	//freopen ("std.out","w",stdout);
	int t, Case = 1;
	scanf("%d", &t);
	while (t--){
		int d,h,b,L;
		scanf("%d%d%d%d", &d, &h, &b, &L);
		int cnt = (b + d - 1) / d;
		len = b / (double)cnt;
		double l = 0, r = h;
		while ((r - l) >= EPS){
			double mid = (l + r) / 2.0;
			if (get_ans(h - mid) * cnt < (double)L)	r = mid;
			else    l = mid;
		}
		if (Case > 1) printf("\n");
		printf("Case %d:\n", Case++);
		printf("%.2f\n", l);
		
	}
	return 0;
}

double get_ans(double h){
	a = 4 * h / len / len;
	return 2 * asr(0, len / 2.0, EPS, simpson(0, len / 2.0));
}

double asr(double a, double b, double eps, double A){
	double c = (a + b) / 2;
	double l = simpson(a, c), r = simpson(c, b);
	if (fabs(l + r - A) <= 15 * eps)	return l + r + (l + r - A) / 15.0;
	return asr(a, c, eps / 2.0, l) + asr(c, b, eps / 2.0, r);
}

inline double f(double x){
	return sqrt(1 + 4 * a * a * x * x);
}

inline double simpson(double a, double b){
	return (f(a) + f(b) + 4 * f((a + b) / 2) ) * (b - a) / 6;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值