膨胀的木棍

一道非常有意思的二分题

描述

当长度为L的一根细木棍的温度升高n度,它会膨胀到新的长度L'=(1+n*C)*L,其中C是热膨胀系数。

当一根细木棍被嵌在两堵墙之间被加热,它将膨胀形成弓形的弧,而这个弓形的弦恰好是未加热前木棍的原始位置。

你的任务是计算木棍中心的偏移距离。

输入

三个非负实数:木棍初始长度(单位:毫米),温度变化(单位:度),以及材料的热膨胀系数。
保证木棍不会膨胀到超过原始长度的1.5倍。

输出

木棍中心的偏移距离(单位:毫米),保留到小数点后第三位。

样例输入

1000 100 0.0001

样例输出

61.329

来源

Waterloo local 2004.06.12

解题思路:

首先我们弄清一个概念,圆上的一条弦把圆分割成两部分,所得的两部分都称为弓形,因它们的形状似弓而得名。

弓形是一个非正式用语。如没有特别指明,弓形通常指的是加上弦后面积不包含圆心的那一部分。面积比较大的部分称为优弓形,而另一部分则称为劣弓形

所以弓形一定在某个圆上,我们就可以借用某些圆的性质了

这可比我一开始想用微积分简单的多了

这道题问的就是我们要知道 h 是多少,而 h 可以表示为 h=r-r*cos(x) 利用这个式子,我们要探求的是否存在单调性, 如果有就可以直接用二分算法就可以了。

我们可以想到二分角度,因为题目说最大不超过 1.5 倍,所以不用担心单调性。

 

代码示例:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define PI (acos(-1))
#define eps (1e-14)

double L,n,C,L2,s,L1;
double ans;// 题目要求答案,即 h 
double rad;// 半径 

int main(){
	cin>>L>>n>>C;
	if(n*C*L<=eps){//如果太小直接输出就可以了 
		cout<<"0.000\n";
		return 0;
	}
	L1=(1+n*C)*L;//加热膨胀后的长度 
	double l,r,mid;//二分的左右边界和中间值 
	l=0;
	r=PI;
	while(l<r-eps){//在这个范围内时二分就可以了,精度问题 
		mid=(l+r)/2;
		rad=L/2/sin(mid/2);
		L2=mid*rad;//L2 表示的是用 mid 求出来的弧长 
		if(L2>=L1) r=mid;
		else l=mid;
	}
	rad=L/2/sin(l/2);
	ans=rad-L/2/tan(l/2);
	printf("%.3lf\n",ans);
	return 0;
}

 还有更优质的题解可以去参考一下:

POJ 1905 Expanding Rods 木棍膨胀_在思索中前行!-CSDN博客

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值