【bzoj1502】[NOI2005]月下柠檬树 自适应Simpson积分
题目描述

输入
输出
输出1个实数,表示树影的面积。四舍五入保留两位小数。
样例输入
2 0.7853981633
10.0 10.00 10.00
4.00 5.00
样例输出
171.97
题解
自适应Simpson积分
根据数学知识:在平行光投影下,圆的半径保持不变,位置为 高度/tanα ;圆台/圆锥的侧面投影为两圆/一圆一点的外公切线。
那么先将圆的位置求出,然后依次求相邻两圆公切线并将线段记录,此时注意内切/内含的两个圆是没有外公切线的。这里求公切线使用了射影定理。
如下图:

其中黑色的是投影后的圆,红色的是公切线段。
那么我们要求的就是最外层轮廓所围成的图形的面积。由于对称性因此只需要求出上半部分然后乘2。
注意到上半部分的外层轮廓形成了连续的一段函数,因此考虑使用自适应Simpson积分来求面积。
Simpson积分:对于三次及以下多项式函数,有 $\int_l^rf(x)dx=(r-l)·\frac {f(l)+f(r)+4f(\frac{l+r}2)}6$ 。
自适应Simpson积分:对于任意连续函数 $f(x)$ 求 $\int_l^rf(x)dx$,先将其当作三次函数使用Simpson积分求出 $[l,r]$ 、$[l,mid]$ 和 $[mid+r]$ 的面积,如果左半部分和右半部分面积之和与总面积之差满足精度要求则返回,否则递归左右并求和作为总面积。
本质上相当于插一个三次函数,如果差得比较多则递归左右。
回过头来看本题,问题变为:给出 $x$ ,求 $f(x)$ 。显然可以在每个圆和每条线段上(如果存在)求出 $x$ 的函数值,取最大值即为 $f(x)$ 。
注意精度要设得小一些,因为求和的部分使误差增大。
时间复杂度 $O(跑得过)$ 。
#include <cmath>
#include <cstdio>
#include <algorithm>
#define N 510
#define eps 1e-5
using namespace std;
struct circle
{
double x , r;
}c[N];
struct line
{
double x1 , y1 , x2 , y2;
}l[N];
double h[N];
int n , m;
inline double squ(double x)
{
return x * x;
}
inline double f(double p)
{
int i;
double ans = 0;
for(i = 1 ; i <= n ; i ++ )
if(p >= c[i].x - c[i].r && p <= c[i].x + c[i].r)
ans = max(ans , sqrt(squ(c[i].r) - squ(p - c[i].x)));
for(i = 1 ; i <= m ; i ++ )
if(p >= l[i].x1 && p <= l[i].x2)
ans = max(ans , l[i].y1 + (p - l[i].x1) * (l[i].y2 - l[i].y1) / (l[i].x2 - l[i].x1));
return ans;
}
inline double calc(double l , double r)
{
return (r - l) * (f(l) + f(r) + f((l + r) / 2) * 4) / 6;
}
double simpson(double l , double r , double s)
{
double mid = (l + r) / 2 , x = calc(l , mid) , y = calc(mid , r);
if(fabs(x + y - s) <= eps) return s;
return simpson(l , mid , x) + simpson(mid , r , y);
}
int main()
{
int i;
double alpha , t , L = 1e9 , R = -1e9;
scanf("%d%lf" , &n , &alpha) , n ++ ;
for(i = 1 ; i <= n ; i ++ ) scanf("%lf" , &h[i]) , h[i] += h[i - 1] , c[i].x = h[i] / tan(alpha);
for(i = 1 ; i < n ; i ++ ) scanf("%lf" , &c[i].r);
for(i = 1 ; i < n ; i ++ )
{
if(c[i + 1].x - c[i].x > fabs(c[i + 1].r - c[i].r))
{
m ++ ;
t = c[i].r * (c[i].r - c[i + 1].r) / (c[i + 1].x - c[i].x) , l[m].x1 = c[i].x + t , l[m].y1 = sqrt(squ(c[i].r) - squ(t));
t = c[i + 1].r * (c[i].r - c[i + 1].r) / (c[i + 1].x - c[i].x) , l[m].x2 = c[i + 1].x + t , l[m].y2 = sqrt(squ(c[i + 1].r) - squ(t));
}
}
for(i = 1 ; i <= n + 1 ; i ++ ) L = min(L , c[i].x - c[i].r) , R = max(R , c[i].x + c[i].r);
printf("%.2lf\n" , 2 * simpson(L , R , calc(L , R)));
return 0;
}
【bzoj1502】[NOI2005]月下柠檬树 自适应Simpson积分的更多相关文章
- [BZOJ 1502] [NOI2005] 月下柠檬树 【Simpson积分】
题目链接: BZOJ - 1502 题目分析 这是我做的第一道 Simpson 积分的题目.Simpson 积分是一种用 (fl + 4*fmid + fr) / 6 * (r - l) 来拟合 fl ...
- [BZOJ1502]月下柠檬树(自适应辛普森积分)
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1387 Solved: 739[Submit][Status] ...
- [日常摸鱼]bzoj1502[NOI2005]月下柠檬树-简单几何+Simpson法
关于自适应Simpson法的介绍可以去看我的另一篇blog http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题意:空间里圆心在同一直线上且底面 ...
- BZOJ 1502 月下柠檬树(simpson积分)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1502 题意:给出如下一棵分层的树,给出每层的高度和每个面的半径.光线是平行的,与地面夹角 ...
- BZOJ1502: [NOI2005]月下柠檬树
Simpson法相当好用啊!神奇的骗分算法! /************************************************************** Problem: 1502 ...
- bzoj 1502 月下柠檬树【Simpson积分】
投影到地面之后,会发现圆形在平行光下面积和形状是不会变的,也就是所要求的图形是若干个圆和把相邻两个圆连起来的公切线所组成的. 公切线和圆间距瞎求一下就行,注意要去掉被完全覆盖的圆 然后simpson即 ...
- 【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分
[BZOJ1502][NOI2005]月下柠檬树 Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树 ...
- 【BZOJ-1502】月下柠檬树 计算几何 + 自适应Simpson积分
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1017 Solved: 562[Submit][Status] ...
- BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1070 Solved: 596[Submit][Status] ...
随机推荐
- 实验一 Java开发环境的熟悉(Linux+Eclipse)
实验一 Java开发环境的熟悉(Linux+Eclipse) 在Linux或Window或macOS中命令行下运行Java 在Linux 或Window或 macOS环境中 IDEA中调试设置断点 实 ...
- WPF ControllTemplate Triggers小记 - 简书
原文:WPF ControllTemplate Triggers小记 - 简书 WPF中,样式模板中如果定义EventTrigger事件方式实现动画.那么需要注意两点: 1.对于绑定的属性的Event ...
- PostgreSQL的hstore初步学习
安装hstore: 进入源代码的 /contrib/hstore 目录,然后执行gmake 和 gmake install: [root@pg200 hstore]# gmake gcc -O2 -W ...
- 1116: [POI2008]CLO
1116: [POI2008]CLO https://lydsy.com/JudgeOnline/problem.php?id=1116 分析: 单独考虑每个联通块的情况. 设这个联通块里有n个点,那 ...
- C#:在AnyCPU模式下使用CefSharp
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客讲述如何在AnyCPU模式下使用CefSharp 因为在某些情况下,不得不用AnyCPU,但是CefS ...
- 16、Java并发编程:Timer和TimerTask
Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...
- 关于nginx反向代理504 gateway time-out配置
问题描述: 使用nginx的默认配置用作后端处理服务的反向代理,针对处理时间超过1分钟的请求,返回504 gateway time-out,但后端服务还在执行中. 原因分析: nginx代理默认超时时 ...
- 二、利用EnterpriseFrameWork快速开发Web系统(B/S)
EnterpriseFrameWork框架实例源代码下载: 实例下载 本章通过一个开发实例来讲解Web系统的开发经过,以及会碰到的一些问题.实例功能就是业务系统中最常见的增.删.改.查来演示,用一个界 ...
- 面试之HTTP基础(不断完善中)
目录 1. HTTP状态码 2.Cookie和Session Cookie Session 3.短连接与长连接 4.HTTPs 加密 5.Http和https的区别 6.HTTP/1.0 与 HTTP ...
- PReLU——Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
1. 摘要 在 \(ReLU\) 的基础上作者提出了 \(PReLU\),在几乎没有增加额外参数的前提下既可以提升模型的拟合能力,又能减小过拟合风险. 针对 \(ReLU/PReLU\) 的矫正非线性 ...