【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] ...
随机推荐
- 20155329实验二 Java面向对象程序设计
实验二 Java面向对象程序设计 1实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 2. 初步掌握单元测试 ...
- 1.Delphi Rest后台+MUI前台开发App前言
尽管不是专业的程序猿,但是对Delphi的喜爱已经10多年了.一直以来用Delphi开发一些小应用若干个,同时用Delphi给朋友开发一些中小型的业务平台也有几个.可以说Delphi对于数据库的操作, ...
- POJ1035_Spell checker_KEY
题目传送门 一道暴力可以过的水题.(直接暴力模拟的那种) 但是我打Trie练练模板,但是TMD因为数组开太小卡了好久. code: #include <cstdio> #include & ...
- jQuery File Upload 文件上传插件使用二 (功能完善)
使用Bootstrap美化进度条 Bootstrap现在几乎是人尽皆知了,根据它提供的进度条组件, 让进度条显得高大尚点 正因为其功能强大,js模块文件之间牵连较深 不好的地方耦合度非常高 重要的参数 ...
- loj2538 「PKUWC 2018」Slay the Spire
pkusc 快到了--做点题涨涨 rp. ref我好菜啊QAQ. 可以发现期望只是一个幌子.我们的目的是:对于所有随机的选择方法(一共 \(\binom{2n}{m}\)种),这些选择方法都最优地打出 ...
- jquery.validate使用 - 4
自定义错误消息的显示方式 默认情况下,验证提示信息用label元素来显示, 并且会添加css class, 通过css可以很方便设置出错控件以及错误信息的显示方式. /* 输入控件验证出错*/form ...
- 【Java】 秒转时分秒天
总有时候会有些需求, 需要用到秒, 比如 JedisCluster 设置过期时间 现在有一个需求是 : 查询接口的缓存设置有效期为:1天+随机时间 基本可以按以下来做: package com.lwc ...
- linux云主机小技巧
微信服务器安装 安装库 python 3.5环境下 pip安装web.py时 会报错 "no module named "utils" 等问题 更换命令为“pip ins ...
- golang笔记2_程序结构
golang程序结构 2.1 命名 Golang中的命名遵循这样一个简单原则,名字的开头必须是字母或者下划线,后面跟字母.数字或者下划线(这里与C语言中是一致的). 在函数内部声明的实体,即局部变量, ...
- Polycarp and Letters(set首战!)
Description Polycarp loves lowercase letters and dislikes uppercase ones. Once he got a string s con ...