描述

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

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

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

输入
三个非负实数:木棍初始长度(单位:毫米),温度变化(单位:度),以及材料的热膨胀系数。

保证木棍不会膨胀到超过原始长度的1.5倍。
输出
木棍中心的偏移距离(单位:毫米),保留到小数点后第三位。
样例输入
  1. 1000 100 0.0001
样例输出
  1. 61.329

直接使用求方程的方式来解题,可能由于其中出现三角函数,解决起来肯定不会那么顺手,而且很难得到一个精确的答案,但是由于弧长和弦长已定,则该圆也能确定了。但是通过画图可以看出来,由于膨胀的长度绝不会超过原长度的50%,因此膨胀圆心角不会超过180度,也不会少于0度。

此题的核心是找到高度h的表达式,然后探求与角或者圆的半径的关系,然后看是否存在某种单调性,采用二分逼近法求解近似值

想明白了后,二分求角度嘛反而不是重点了,关键是角度与弦长的单调性关系值得推敲

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<math.h>
  4. int main()
  5. {
  6. double l, ll, rig, lef, mid, n, c;
  7. scanf("%lf%lf%lf", &l, &n, &c);
  8.  
  9. if(l<1e-14)
  10. {
  11. printf("0.000\n");
  12. return 0;
  13. }
  14. ll=l*(1+n*c);
  15. lef=0.0; //角的极小值
  16. rig=asin(1.0); //角的极大值
  17. //由于三角函数转换,得到 h= (l/2)*tan(@/2) , 所以h只与角@有关,使用二分逼近法去求解最接近的@即可
  18. //注意,二分验证是让 ll与角@ 计算得到的 木棍原始长度l`=ll*sin@/@ 与 l 进行比较,且l`与@成反比例关系
  19. while(rig-lef>1e-14) //在极大值与极小值之间进行二分,这个地方精度控制太低就过不了了。精度要求很高。
  20. {
  21. mid=(rig+lef)/2;
  22. if(ll*sin(mid)/mid<=l)
  23. rig=mid;
  24. else
  25. lef=mid;
  26. }
  27. printf("%.3lf\n", l/2*tan(lef/2));
  28. return 0;
  29. }

解法2,装载自

大致题意:

一根两端固定在两面墙上的杆 受热弯曲后变弯曲

求前后两个状态的杆的中点位置的距离

解题思路:

几何和二分的混合体

 

如图,蓝色为杆弯曲前,长度为L

红色为杆弯曲后,长度为s

h是所求

依题意知

S=(1+n*C)*L

又从图中得到三条关系式;

(1)       角度→弧度公式  θr = 1/2*s

(2)       三角函数公式  sinθ= 1/2*L/r

(3)       勾股定理  r^2 – ( r – h)^2 = (1/2*L)^2

把四条关系式化简可以得到

逆向思维解二元方程组:

要求(1)式的h,唯有先求r

但是由于(2)式是三角函数式,直接求r比较困难

因此要用顺向思维解方程组:

在h的值的范围内枚举h的值,计算出对应的r,判断这个r得到的(2)式的右边  与 左边的值S的大小关系  ( S= (1+n*C)*L )

很显然的二分查找了。。。。。

那么问题只剩下 h 的范围是多少了

下界自然是0 (不弯曲)

关键确定上界

题中提及到

Input data guarantee that no rod expands by more than one half of its original length.

意即输入的数据要保证没有一条杆能够延伸超过其初始长度的一半

就是说 S max = 3/2 L

理论上把上式代入(1)(2)方程组就能求到h的最小上界,但是实际操作很困难

因此这里可以做一个范围扩展,把h的上界扩展到 1/2L  ,不难证明这个值必定大于h的最小上界,那么h的范围就为  0<=h<1/2L

这样每次利用下界low和上界high就能得到中间值mid,寻找最优的mid使得(2)式左右两边差值在精度范围之内,那么这个mid就是h

精度问题是必须注意的

由于数据都是double,当low无限接近high时, 若二分查找的条件为while(low<high),会很容易陷入死循环,或者在得到要求的精度前就输出了不理想的“最优mid”

精度的处理方法参考我的程序

  1. #include<iostream>
  2. #include<math.h>
  3. #include<iomanip>
  4. using namespace std;
  5. const double esp=1e-5; //最低精度限制
  6.  
  7. int main(void)
  8. {
  9. double L,n,c,s; //L:杆长 ,n:温度改变度 , c:热力系数 ,s:延展后的杆长(弧长)
  10. double h; //延展后的杆中心 到 延展前杆中心的距离
  11. double r; //s所在圆的半径
  12.  
  13. while(cin>>L>>n>>c)
  14. {
  15. if(L<0 && n<0 && c<0)
  16. break;
  17. double low=0.0; //下界
  18. double high=0.5*L; // 0 <= h < 1/2L (1/2L并不是h的最小上界,这里做一个范围扩展是为了方便处理数据)
  19.  
  20. double mid;
  21. s=(1+n*c)*L;
  22. while(high-low>esp) //由于都是double,不能用low<high,否则会陷入死循环
  23. { //必须限制low与high的精度差
  24. mid=(low+high)/2;
  25. r=(4*mid*mid+L*L)/(8*mid);
  26.  
  27. if( 2*r*asin(L/(2*r)) < s ) //h偏小
  28. low=mid;
  29. else //h偏大
  30. high=mid;
  31. }
  32. h=mid;
  33.  
  34. cout<<fixed<<setprecision(3)<<h<<endl;
  35. }
  36. return 0;
  37. }

解法3

这个题有两个难点

1、解方程

图片大了点呵。。Retina屏的水果本就是不错!

这方程是超越方程,只有数值解,那怎么办呢?

2、二分单调性证明

证明如下:

上面的方程,另左边等于s,则可推得弧长s与h间关系如下:

绘制该函数图像如下:

可知该函数是随l和s单增的,故可用二分逼近。

上图是刚才那个超越方程的隐函数围道图像,也可证明。

另提供几何证明(为什么h越大s越大,可以利用二分来逼近这h在给定s下的最大值)

下面是代码:

  1. #include <iostream>
  2. #include <math.h>
  3. #include <iomanip>
  4.  
  5. using namespace std;
  6.  
  7. #define eps 1e-5
  8.  
  9. int main() {
  10. double L, n, c, s;
  11. double h;
  12. double r;
  13. while (cin >> L >> n >> c) {
  14. if (L < 0 && n < 0 && c < 0)
  15. break;
  16. double low = 0.0;
  17. double high = 0.5 * L;
  18. double mid;
  19. s = (1 + n * c) * L;
  20. while (high - low > eps) {
  21. mid = (low + high) / 2;
  22. r = (4 * mid * mid + L * L) / (8 * mid);
  23. if (2 * r * asin(L / (2 * r)) < s)
  24. low = mid;
  25. else
  26. high = mid;
  27. }
  28. h = mid;
  29. cout << fixed << setprecision(3) << h << endl;
  30. }
  31. }

POJ 1905 Expanding Rods 木棍膨胀的更多相关文章

  1. poj 1905 Expanding Rods(木杆的膨胀)【数学计算+二分枚举】

                                                                                                         ...

  2. POJ 1905 Expanding Rods

                           Expanding Rods Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1 ...

  3. POJ 1905 Expanding Rods(二分)

    Expanding Rods Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 20224 Accepted: 5412 Descr ...

  4. POJ 1905 Expanding Rods 二分答案几何

    题目:http://poj.org/problem?id=1905 恶心死了,POJ的输出一会要lf,一会要f,而且精度1e-13才过,1e-12都不行,错了一万遍终于对了. #include < ...

  5. POJ - 1905 Expanding Rods(二分+计算几何)

    http://poj.org/problem?id=1905 题意 一根两端固定在两面墙上的杆,受热后变弯曲.求前后两个状态的杆的中点位置的距离 分析 很明显需要推推公式. 由②的限制条件来二分角度, ...

  6. POJ 1905 Expanding Rods( 二分搜索 )

    题意:一个钢棍在两面墙之间,它受热会膨胀成一个圆弧形物体,这个物体长 S = ( 1 + n * C ) * L,现在给出原长 L ,温度改变量 n ,和热膨胀系数 C,求膨胀后先后中点的高度差. 思 ...

  7. poj 1905 Expanding Rods (数学 计算方法 二分)

    题目链接 题意:将长度为L的棒子卡在墙壁之间.现在因为某种原因,木棒变长了,因为还在墙壁之间,所以弯成了一个弧度,现在求的是弧的最高处与木棒原先的地方的最大距离. 分析: 下面的分析是网上别人的分析: ...

  8. poj 1905 Expanding Rods 二分

    /** 题解晚上写 **/ #include <iostream> #include <math.h> #include <algorithm> #include ...

  9. POJ 1905 Expanding Rods (求直杆弯曲拱起的高度)(二分法,相交弦定理)

    Description When a thin rod of length L is heated n degrees, it expands to a new length L' = (1+n*C) ...

随机推荐

  1. spring cloud 路由网关zuul基本使用

    在微服务架构中,需要几个关键的组件,服务注册与发现.服务消费.负载均衡.断路器.智能路由.配置管理等,由这几个组件可以组建一个简单的微服务架构.客户端的请求首先经过负载均衡(zuul.Ngnix),再 ...

  2. 手机app数据的爬取之mitmproxy安装教程

    mitmproxy是一个支持HTTP和HTTPS的抓包程序,类似Fiddler.Charles的功能,只不过它通过控制台的形式操作. 此外,mitmproxy还有两个关联组件,一个是mitmdump, ...

  3. Vs2015 本地git获取的代码目录文件修改后,启动提示error:Unable to start program “C:\Program Files\dotnet\dotnet.exe” 已解决.

    http://stackoverflow.com/questions/39938453/unable-to-start-program-c-program-files-dotnet-dotnet-ex ...

  4. JS高级程序设计2

    面向对象 ,基本模式.对象字面量模式.工厂模式.构造函数模式.原型模式.组合构造函数和原型模式.其他模式见电子书:动态原型模式.寄生构造函数模式(不推荐).稳妥构造函数模式(要求安全的环境,不使用ne ...

  5. 二叉查找树及B-树、B+树、B*树变体

    动态查找树主要有二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree), 红黑树 (Red-Black Tree ), 都是典型的 ...

  6. 用Web api /Nancy 通过Owin Self Host简易实现一个 Http 服务器

    过去做 端游的Http 服务器 用的WebApi 或者Mvc架构,都是放在iis...而我已经是懒出一个地步,并不想去配iis,或者去管理iis,所以我很喜欢 Self host 的启动方式. C#做 ...

  7. bzoj3769 spoj 8549 BST again

    题解: 比较水的题目 普通dp其实复杂度还是比较大的 可以任意模数ntt优化.. 但好像没人写.. 代码: #include <bits/stdc++.h> using namespace ...

  8. Principles and strategies for mathematics study

    Make mathematics study a habit with dogged perseverance Don't build mansion on top of loose sand. Co ...

  9. [转]xshell使用技巧

    https://yq.aliyun.com/articles/44721 xshell是我用过的最好用的ssh客户端工具,没有之一.这个软件完全免费,简单易用,可以满足通过ssh管理linux vps ...

  10. exshop第6天

    发现grails mongodb插件中的一个BUG并进行了提交,grails项目管理人员还进行了回复,主要是配置failOnError 后不起作用了,不过项目负责人还是确认了这个问题,估计会比较快的解 ...