openjudge-膨胀的木棍

http://noi.openjudge.cn/ch0111/09/

总时间限制: 1000ms  内存限制: 65536kB
描述

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

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

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

输入

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

输出

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

样例输入

1000 100 0.0001

样例输出

61.329

参考:

http://blog.csdn.net/jeremygjy/article/details/49686943

http://blog.csdn.net/txl199106/article/details/49332261

 1 #include<stdio.h>
 2 #include<math.h>
 3 #define PI (acos(-1))
 4 #define eps (1e-14)
 5 int main(int argc, char *argv[])
 6 {
 7     double L,n,C,L1;
 8
 9     double minCentralAngle,maxCentralAngle,CentralAngle;
10     double radius,L2;
11     double ans;
12
13     scanf("%lf%lf%lf",&L,&n,&C);
14
15     if(n*C*L<=eps)   //假如膨胀量太小就不用计算了,直接认为结果就是0.
16     {
17         printf("0.000\n");
18         return 0;
19     }
20
21     L1=(1+n*C)*L;
22
23     //下面对圆心角进行二分枚举
24     //(膨胀量不超过原来的1.5倍,
25     //分析圆的半周长PI*R与直径2*R的关系可知圆心角范围0~2*PI而且不可能取2*PI)
26     minCentralAngle=0;//圆心角的极小值
27     maxCentralAngle=PI;//圆心角的极大值
28     while(minCentralAngle<maxCentralAngle-eps)
29     {
30         CentralAngle=(minCentralAngle+maxCentralAngle)/2;
31         radius=L/2/sin(CentralAngle/2);
32         L2=CentralAngle*radius;
33         if(L2>=L1)//当弦长固定时,圆心角越大 ,弧长就越大
34             maxCentralAngle=CentralAngle;
35         else if(L2<L1)
36             minCentralAngle=CentralAngle;
37     }
38     radius=L/2/sin(minCentralAngle/2);
39     ans=radius-L/2/tan(minCentralAngle/2);
40     printf("%.3lf\n",ans);
41     return 0;
42 }

一定要注意:我们需要二分的内容是当前角度,那么角度的范围可以很容易发现,因为木管长度不超过1.5倍那么就定角度为0-π因为如果圆心角过小会发现半径十分的大根本存不下,其实这种情况的时候木棍长度的变化也是十分的小的那么

if(n * c * L <= eps) 
判断一下如果满足那么直接就输出0.000,

另外要注意:当弦长固定时,圆心角越大 ,弧长就越大 。

网友JeremyGJY的代码和分析很好,摘抄一下:

JeremyGJY的代码:

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 using namespace std;
 5 const double PI = asin(1.0);
 6 const double eps = 1e-14;
 7 int main(){
 8     double Len1, Len2, Temp, ks;
 9     while(scanf("%lf%lf%lf", &Len1, &Temp, &ks) != EOF){
10         Len2 = (1.0 + Temp * ks) * Len1;
11         double l=0, r=PI;
12         if(Temp * ks * Len1 <= eps){
13             printf("%.3lf\n", 0.0);
14             continue;
15         }
16         while(l < r - eps){
17             double mid = (l + r)/2.0;
18             if(Len1/sin(mid)*PI*(mid/PI) >= Len2)
19                 r = mid;
20             else l = mid;
21         }
22         printf("%.3lf\n", Len1/2/sin(l)-Len1/2/sin(l)*cos(l));
23     }
24
25     return 0;
26 }

csdn网友Tank_long的分析更精彩,只不过下面这个图的公式似乎有点乱。

公式大概如下:

首先要注意θ角是圆心角的一半。然后根据数学公式有:

sinθ=2sin(θ/2)cos(θ/2)

1-cosθ=2sin(θ/2)2

然后还要注意根据直角三角形正弦的定义有:L=2*R*sinθ

根据弧长公式有LL=2*R*θ

所以h=R-R*cosθ=R*(1-cosθ)=L/(2*sinθ)*(1-cosθ)=L/(2*sinθ)*(2sin(θ/2)2)=L/( 2*  ( 2*sin(θ/2)*cos(θ/2)  )    )*(2sin(θ/2)2 )

最后h=L/2*tan(θ/2)

注意到θ是圆心角的一半,所以θ得区间是0~PI,根据正切函数图形性质可以知道当L固定时,h跟θ是成正比关系的。

Tank_long的代码:(不得不佩服起数学功底啊……)

 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*[email protected]/@ 与 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 }  

时间: 2024-10-29 19:07:27

openjudge-膨胀的木棍的相关文章

整理小朋友在noi.openjudge上的作业(1)

NOI(题库正在建设中,做题纪录有可能会被删除,请注意) 第一章的统计放前面 1 编程基础之输入输出 10 0 0% 最基础有空补刷 2 编程基础之变量定义.赋值及转换 10 0 0% 最基础有空补刷 3 编程基础之算术表达式与顺序执行 20 0 0% 最基础有空补刷 4 编程基础之逻辑表达式与条件分支 21 0 0% 最基础有空补刷 5 编程基础之循环控制 45 10 22% 最基础有空补刷 6 编程基础之一维数组 15 5 33% 最基础有空补刷 7 编程基础之字符串 35 0 0% 有必要

二分 题目 压缩打包 Special Judge? 不不不 当然不是

http://noi.openjudge.cn/ch0111/ No 题目 分数 01 查找最接近的元素 10 3176 02 二分法求函数的零点 10 2181 03 矩形分割 10 1420 04 网线主管 10 1648 05 派 10 1581 06 月度开销 10 1449 07 和为给定数 10 1906 08 不重复地输出数 10 1790 09 膨胀的木棍 10 768 10 河中跳房子 10 2027 ------------------------------萌萌的分割线--

【noiOJ】p7939

09:膨胀的木棍 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 当长度为L的一根细木棍的温度升高n度,它会膨胀到新的长度L'=(1+n*C)*L,其中C是热膨胀系数. 当一根细木棍被嵌在两堵墙之间被加热,它将膨胀形成弓形的弧,而这个弓形的弦恰好是未加热前木棍的原始位置. 你的任务是计算木棍中心的偏移距离. 输入 三个非负实数:木棍初始长度(单位:毫米),温度变化(单位:度),以及材料的热膨胀系数.保证木棍不会膨胀到超过原始长度的1.5倍. 输出 木棍中

BZOJ 1044 木棍分割 解题报告(二分+DP)

来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3162  Solved: 1182[Submit][Status][Discuss] Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个

”乳罩图“ 的完美匹配:高温展开与顶点膨胀技巧

本文的目的是通过一个例子来介绍统计力学中精确可解模型的两个经典方法:高温展开和顶点膨胀. 问题是这样的:考虑这样一张非常类似 "bra" 的图: 注意这个图不是平面图!上面两条实线的边与下面两条实线的边分别是粘在一起的,左边两条实线的边和右边的两条实线的边也是分别粘合的:虚线部分不是边,只是用来描述粘合定向的.因此这个图的每个顶点的度数都是 3. 想象它的立体图:这是一个乳罩,已经穿戴在某个美女身上,则上下和左右的实线边相当于系的绳子. 问这个图有多少不同的完美匹配? 答案是 $64$

[OpenJudge] 百练2754 八皇后

八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题一共有92组解(即92个不同的皇后串).给出一个数b,要求输出第b个串.串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小. I

opencv2函数学习之erode、dilate:图像腐蚀和膨胀

图像腐蚀和图像膨胀是图像中两种最基本形态学操作. void erode( const Mat& src, Mat& dst, const Mat& element,Point anchor=Point(-1,-1), int iterations=1,int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() ); void dilate( const Ma

P1120 小木棍 [数据加强版]

题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度. 输入输出格式 输入格式: 输入文件共有二行. 第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65 (管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!) 第二行为N个用空个隔开的正整数,表示N根小木棍的长度. 输出格式: 输出文件仅一行,表示要求

基于Qt的OpenGL可编程管线学习(10)- 膨胀与腐蚀

膨胀:取一个像素周围的点,取最亮的点为当前的点颜色,为膨胀效果 腐蚀:取一个像素周围的点,取最暗的点为当前的点颜色,为腐蚀效果 膨胀Fragment Shader varying vec2 M_coord; varying vec3 M_normal; varying vec3 M_WordPos; uniform sampler2D U_MainTexture; uniform sampler2D U_SubTexture; void main() {     vec4 maxValue=ve