【洛谷】P4207 [NOI2005]月下柠檬树
题解
原来自适应simpson积分是个很简单的东西!
我们尝试分析一下影子,圆的投影还是圆,圆锥的尖投影成一个点,而圆台的棱是圆的公切线,我们把圆心投影出来,发现平面上圆心的距离是两两高度差/tan(alpha)
这是一个轴对称图形,我们只需要求一侧就好了
用simpson积分的公式
\(S = \frac{b - a}{6}(f(a) + 4 * f(\frac{a + b}{2}) + f(b))\)
计算区间就好了,啥,你说肯定不对……
确实肯定不对,然而你可以递归,如何判断这个区间计算的和正确答案相差无几呢,就是左右分别积分出来的值和整个区间的积分相差小于精度的时候就可以认为积分正确了,返回即可,否则左右递归计算积分
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <ctime>
//#define ivorysi
#define MAXN 505
#define eps 1e-7
#define pb push_back
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
inline db o(db x) {
return x * x;
}
bool dcmp(db a,db b) {
return fabs(a - b) <= eps;
}
struct Point {
db x,y;
Point(){}
Point(db _x,db _y) {
x = _x;y = _y;
}
friend Point operator + (const Point &a,const Point &b) {
return Point(a.x + b.x,a.y + b.y);
}
friend Point operator - (const Point &a,const Point &b) {
return Point(a.x - b.x,a.y - b.y);
}
friend Point operator * (const Point &a,const db &d) {
return Point(a.x * d,a.y * d);
}
friend db operator * (const Point &a,const Point &b) {
return a.x * b.y - a.y * b.x;
}
db norm() {
return sqrt(x * x + y * y);
}
friend db dot(const Point &a,const Point &b) {
return a.x * b.x + a.y * b.y;
}
}P[MAXN];
struct Seg {
Point a,b;
db d;
Seg(){}
Seg(Point _a,Point _b) {
a = _a;b = _b;
d = (b.y - a.y) / (b.x - a.x);
}
friend Point Cross_Point(const Seg &s,const Seg &t) {
db S1 = (s.a - t.a) * (t.b - t.a);
db S2 = (s.b - t.b) * (t.a - t.b);
return s.a + (s.b - s.a) * (S1 / (S1 + S2));
}
}S[MAXN];
db alpha;
db H[MAXN],R[MAXN];
int N;
db F(db x) {
db res = 0;
for(int i = 1 ; i <= N ; ++i) {
if(i != N) {
if(P[i + 1].x - P[i].x > fabs(R[i] - R[i + 1])) {
if(S[i].a.x + eps <= x && x <= S[i].b.x - eps) {
res = max(res,S[i].a.y + (x - S[i].a.x) * S[i].d);
}
}
}
if(x >= P[i].x - R[i] && x <= P[i].x + R[i]) {
res = max(res,sqrt(o(R[i]) - o(P[i].x - x)));
}
}
return res;
}
db calc(db L,db R) {
db mid = (L + R) / 2;
return (R - L) * (F(L) + F(R) + 4 * F((L + R) / 2)) / 6;
}
db Simpson(db L,db R) {
db mid = (L + R) / 2;
db Slr = calc(L,R),Sl = calc(L,mid),Sr = calc(mid,R);
if(dcmp(Slr,Sl + Sr)) return Sl + Sr;
else return Simpson(L,mid) + Simpson(mid,R);
}
void Init() {
scanf("%d%lf",&N,&alpha);
++N;
for(int i = N ; i >= 1; --i) scanf("%lf",&H[i]);
R[1] = 0;
for(int i = N ; i >= 2; --i) scanf("%lf",&R[i]);
for(int i = 1 ; i <= N ; ++i) H[i] /= tan(alpha);
P[1] = Point(0,0);
for(int i = 2 ; i <= N ; ++i) {
P[i] = Point(P[i - 1].x + H[i - 1],0);
}
}
void Solve() {
db r = 0,l = 0;
for(int i = 1 ; i <= N ; ++i) {
l = min(P[i].x - R[i],l);
r = max(r,P[i].x + R[i]);
}
for(int i = 1 ; i < N ; ++i) {
if(P[i + 1].x - P[i].x > fabs(R[i] - R[i + 1])) {
db C = (R[i] - R[i + 1]) / (P[i + 1].x - P[i].x);
db s1 = P[i].x + R[i] * C,s2 = P[i + 1].x + R[i + 1] * C;
db h1 = sqrt(o(R[i]) - o(P[i].x - s1)),h2 = sqrt(o(R[i + 1]) - o(P[i + 1].x - s2));
S[i] = Seg(Point(s1,h1),Point(s2,h2));
}
}
printf("%.2lf\n",Simpson(l,r) * 2);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}
【洛谷】P4207 [NOI2005]月下柠檬树的更多相关文章
- 洛谷P4207 [NOI2005]月下柠檬树(计算几何+自适应Simpson法)
题面 传送门 题解 我还好奇自适应辛普森法干嘛用的呢--突然想起来积分的一个用处就是求曲边图形的面积-- 我们先来考虑一下这些投影是什么形状 一个圆的投影还是它自己 一个圆锥的投影是一个圆加上一个点, ...
- 5.21 省选模拟赛 luogu P4207 [NOI2005]月下柠檬树 解析几何 自适应辛普森积分法
LINK:月下柠檬树 之前感觉这道题很鬼畜 实际上 也就想到辛普森积分后就很好做了. 辛普森积分法的式子不再赘述 网上多的是.值得一提的是 这道题利用辛普森积分法的话就是一个解析几何的问题 而并非计算 ...
- BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1070 Solved: 596[Submit][Status] ...
- [NOI2005]月下柠檬树[计算几何(simpson)]
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1169 Solved: 626[Submit][Status] ...
- 【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分
[BZOJ1502][NOI2005]月下柠檬树 Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树 ...
- [NOI2005]月下柠檬树
题意 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser autoint Logout 捐赠本站 Probl ...
- BZOJ1502:[NOI2005]月下柠檬树——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1502 https://www.luogu.org/problemnew/show/P4207 李哲 ...
- 1502: [NOI2005]月下柠檬树 - BZOJ
Description Input 文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度).第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的 ...
- [NOI2005]月下柠檬树(计算几何+积分)
题目描述 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔 地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思 索着人生的哲理. 李哲是一个喜爱思考的孩子,当他看 ...
随机推荐
- Hadoop生态圈-hive五种数据格式比较
Hadoop生态圈-hive五种数据格式比较 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- day12 继承
设计原则:开闭原则:对于拓展open,对于修改close. 类与类的关系:1.is a(继承关系) 2.has a(组合关系) 继承的优点:1.代码的可重用性 2.父类的属性和方法用于子类 3.子类可 ...
- bootstrap-switch
首先需要引入bootstrap的css和js文件,再引入bootstrap-switch.css和bootstrap-switch.js文件 <script type="text/ja ...
- android studio run 的时候,报the apk file does not exist on disk,
1.首先 clean rebuild,重启,不能解决的话,再找到这个 然后是这里: 不用填,点ok,ok即可,他喵的,卡我俩小时
- 网站监控系统安装部署(zabbix,nagios)
zabbix分布式监控系统安装部署 官方网站链接 https://www.zabbix.com/documentation/2.0/manual/installation 安装环境说明 参考地址 ht ...
- 从零搭建SSM框架(一)搭建工程
工程结构 一.cnki-parent 1.新建maven project 2.pom.xml <project xmlns="http://maven.apache.org/POM/ ...
- 《PHP和MySQL Web开发》读书笔记(上篇)
最近过得太浮躁了,实在自己都看不下去了,看了PHP圣经之后,觉得非常有必要要总结一下. Chapter1.快速入门 ·PHP标记:总共有三种风格,常用的还是XML风格为主 <?php echo ...
- 搭建zookeeper单机版以及简单命令的使用
1:创建目录 #数据目录dataDir=/opt/hadoop/zookeeper-3.3.5-cdh3u5/data#日志目录dataLogDir=/opt/hadoop/zookeeper-3.3 ...
- (转)Oracle 字符集的查看和修改
一.什么是Oracle字符集 Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系.ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据.它使数据库 ...
- HDU 1010 Tempter of the Bone (广搜+减枝)
题目链接 Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. How ...