1502: [NOI2005]月下柠檬树

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1387  Solved: 739
[Submit][Status][Discuss]

Description

李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地
坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理。李哲是一个喜爱思考的孩子,当他看到在月光的照射下
柠檬树投在地面上的影子是如此的清晰,马上想到了一个问题:树影的面积是多大呢?李哲知道,直接测量面积是
很难的,他想用几何的方法算,因为他对这棵柠檬树的形状了解得非常清楚,而且想好了简化的方法。李哲将整棵
柠檬树分成了n 层,由下向上依次将层编号为1,2,…,n。从第1到n-1 层,每层都是一个圆台型,第n 层(最上面一
层)是圆锥型。对于圆台型,其上下底面都是水平的圆。对于相邻的两个圆台,上层的下底面和下层的上底面重合
。第n 层(最上面一层)圆锥的底面就是第n-1 层圆台的上底面。所有的底面的圆心(包括树顶)处在同一条与地面垂
直的直线上。李哲知道每一层的高度为h1,h2,…,hn,第1 层圆台的下底面距地面的高度为h0,以及每层的下底面
的圆的半径r1,r2,…,rn。李哲用熟知的方法测出了月亮的光线与地面的夹角为alpha。
为了便于计算,假设月亮的光线是平行光,且地面是水平的,在计算时忽略树干所产生的影子。
李哲当然会算了,但是他希望你也来练练手

Input

第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度)。
第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的高度和每层的高度。
第3行包含n个实数r1,r2,…,rn,表示柠檬树每层下底面的圆的半径。
上述输入文件中的数据,同一行相邻的两个数之间用一个空格分隔。
输入的所有实数的小数点后可能包含1至10位有效数字。
1≤n≤500,0.3<alpha<π/2,0<hi≤100,0<ri≤100

Output

输出1个实数,表示树影的面积。四舍五入保留两位小数。

Sample Input

2 0.7853981633
10.0 10.00 10.00
4.00 5.00

Sample Output

171.97

HINT

Source

[Submit][Status][Discuss]

这个题的正解是各种分类讨论求面积,但是可以用辛普森积分骗分。
关于辛普森积分的推导可以看 https://www.zhihu.com/question/47728235
其实这个东西很好卡掉,但是对于很多数据还是可以较为精确地出解的。

首先发现要求的东西是轴对称的,这意味着我们可以只求x坐标上面的函数区域没。这个图像的解析式还是很难求,但是对于每个横坐标上对应的函数值可以比较轻松地求出,这个时候就可以用Simpson积分了。
普通辛普森积分根本不可能出解,因为仅仅一个二次函数不可能拟合这么复杂的图像。但是要分成很多份的话时间复杂度又过高,这个时候就需要引入自适应:如果要对[a,b]积分,可以先对[a,b]拟合,再对[a,(a+b)/2]和[(a+b)/2,b]拟合,如果两个相差很小则直接退出,否则继续递归。
个人认为这个方法在这里可以成功很大程度是因为图像中有很多直线围城的区域,而自适应Simpson积分在直线积分方面的表现应该是很不错的。

具体做法看 https://www.cnblogs.com/DaD3zZ-Beyonder/p/5676841.html
上面讲的很清楚了,直接作为模板即可。

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #define rep(i,l,r) for (int i=l; i<=r; i++)
  5. typedef double db;
  6. using namespace std;
  7.  
  8. const int N=;
  9. double eps=1e-,inf=1e12;
  10. int n,num;
  11. db alpha;
  12. struct P{ db x,y; P(db X=,db Y=){ x=X; y=Y; } };
  13. struct Ci{ db r; P c; Ci (P C=(P(,)),db R=):c(C),r(R){}; }C[N];
  14.  
  15. struct Li{
  16. P s,t; db k,b;
  17. Li (P S=P(,),P T=P(,)){
  18. s=S,t=T; if (s.x>t.x) swap(s,t);
  19. k=(s.y-t.y)/(s.x-t.x); b=s.y-k*s.x;
  20. }
  21. db f(db x){ return k*x+b; }
  22. }l[N];
  23.  
  24. int dcmp(db x){ if (fabs(x)<eps) return ; return (x<) ? - : ; }
  25. db F(db x){
  26. db res=;
  27. rep(i,,n){
  28. db d=fabs(x-C[i].c.x);
  29. if (dcmp(d-C[i].r)>) continue;
  30. db len=*sqrt(C[i].r*C[i].r-d*d);
  31. res=max(res,len);
  32. }
  33. rep(i,,num) if (x>l[i].s.x && x<=l[i].t.x) res=max(res,*l[i].f(x));
  34. return res;
  35. }
  36.  
  37. db calc(db l,db r){ db mid=(l+r)/; return (F(l)+F(r)+F(mid)*)*(r-l)/; }
  38. db Simpson(db l,db r,db now){
  39. db mid=(l+r)/,x=calc(l,mid),y=calc(mid,r);
  40. if (!dcmp(now-x-y)) return now; else return Simpson(l,mid,x)+Simpson(mid,r,y);
  41. }
  42.  
  43. void solve(){
  44. db L=inf,R=-inf;
  45. rep(i,,n+) L=min(L,C[i].c.x-C[i].r),R=max(R,C[i].c.x+C[i].r);
  46. rep(i,,n){
  47. db d=C[i+].c.x-C[i].c.x;
  48. if (dcmp(d-fabs(C[i].r-C[i+].r))<) continue;
  49. db sina=(C[i].r-C[i+].r)/d,cosa=sqrt(-sina*sina);
  50. l[++num]=Li(P(C[i].c.x+C[i].r*sina,C[i].r*cosa),P(C[i+].c.x+C[i+].r*sina,C[i+].r*cosa));
  51. }
  52. printf("%.2lf\n",Simpson(L,R,calc(L,R)));
  53. }
  54.  
  55. int main(){
  56. scanf("%d%lf",&n,&alpha); db h,r;
  57. rep(i,,n+)
  58. scanf("%lf",&h),C[i]=Ci((P((h/tan(alpha))+C[i-].c.x,)),);
  59. rep(i,,n) scanf("%lf",&r),C[i].r=r;
  60. solve();
  61. return ;
  62. }

[BZOJ1502]月下柠檬树(自适应辛普森积分)的更多相关文章

  1. 【bzoj1502】[NOI2005]月下柠檬树 自适应Simpson积分

    题目描述 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理.李哲是一个喜爱思考的孩子,当他看到在月 ...

  2. [BZOJ 1502] [NOI2005] 月下柠檬树 【Simpson积分】

    题目链接: BZOJ - 1502 题目分析 这是我做的第一道 Simpson 积分的题目.Simpson 积分是一种用 (fl + 4*fmid + fr) / 6 * (r - l) 来拟合 fl ...

  3. BZOJ 1502 月下柠檬树(simpson积分)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1502 题意:给出如下一棵分层的树,给出每层的高度和每个面的半径.光线是平行的,与地面夹角 ...

  4. bzoj 1502 月下柠檬树【Simpson积分】

    投影到地面之后,会发现圆形在平行光下面积和形状是不会变的,也就是所要求的图形是若干个圆和把相邻两个圆连起来的公切线所组成的. 公切线和圆间距瞎求一下就行,注意要去掉被完全覆盖的圆 然后simpson即 ...

  5. 【BZOJ-1502】月下柠檬树 计算几何 + 自适应Simpson积分

    1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: 562[Submit][Status] ...

  6. 【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分

    [BZOJ1502][NOI2005]月下柠檬树 Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树 ...

  7. 5.21 省选模拟赛 luogu P4207 [NOI2005]月下柠檬树 解析几何 自适应辛普森积分法

    LINK:月下柠檬树 之前感觉这道题很鬼畜 实际上 也就想到辛普森积分后就很好做了. 辛普森积分法的式子不再赘述 网上多的是.值得一提的是 这道题利用辛普森积分法的话就是一个解析几何的问题 而并非计算 ...

  8. BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]

    1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1070  Solved: 596[Submit][Status] ...

  9. [NOI2005]月下柠檬树(计算几何+积分)

    题目描述 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔 地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思 索着人生的哲理. 李哲是一个喜爱思考的孩子,当他看 ...

随机推荐

  1. java AWT repaint paint update 方法

    paint(Graphic g): awt调用这个方法有2种形式.程序驱动方式和系统驱动方式. 在系统驱动的情况下(比如界面第一次显示组件),系统会判断组件的显示区域,然后向事件分发线程发出调用pai ...

  2. HDU 1059 完全背包

    Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  3. [lucene系列笔记3]用socket把lucene做成一个web服务

    上一篇介绍了用lucene建立索引和搜索,但是那些都只是在本机上运行的,如果希望在服务器上做成web服务该怎么办呢? 一个有效的方法就是用socket通信,这样可以实现后端与前端的独立,也就是不管前端 ...

  4. TCP ------ TCP创建服务器中出现的套接字

    在服务器端,socket()返回的套接字用于监听(listen)和接受(accept)客户端的连接请求.这个套接字不能用于与客户端之间发送和接收数据. accept()接受一个客户端的连接请求,并返回 ...

  5. session超时设置+超时页面跳转

    session超时设置,方法有三种: (1)在主页面或者公共页面中加入:session.setMaxInactiveInterval(600);参数600单位是秒,即在没有10分钟活动后,sessio ...

  6. C#与数据库的连接的三种方式

    学习了.net的知识从C#一直到MVC,我一直觉得基础很重要,最近有复习一下数据库连接的三种方式 1 返回结果集的一张表 public static DataTable ExecuteDataTabl ...

  7. ${pageContext.request.contextPath}的解释以及和request.contextPath的区别

    JSP中究竟采用绝对路径还是采用相对路径随着所采用技术的越来越复杂,这个问题也变得越来越难以解决. 1)采用相对路径遇到的问题 l 相对路径固然比较灵活,但如果想复制页面内的代码却变得比较困难,因为不 ...

  8. DOM创建和删除节点

    一.创建节点 3步 1.创建空元素对象: var newElem=document.createElement("标签名"); 例如:var a=document.createEl ...

  9. SSL步骤

    SSL步骤 被认证的服务器 1.创建keystore 2.创建信任证书 3.导出信任证书供客户端使用 客户端 1.创建keystore(如果不存在) 2.导入信任证书

  10. 【洛谷 P4555】 [国家集训队]最长双回文串 (Manacher)

    题目链接 \(|S|<=10^5\),时间还是很宽松的. 允许我们使用线性/\(N\log N\)/甚至\(N \sqrt N\)的算法. 设\(l[i]\)表示以\(a[i]\)结尾的最长回文 ...