Portal -->bzoj1502

Solution

  额其实说实在这题我一开始卡在了。。这个阴影长啥样上QwQ

  首先因为是平行光线然后投影到了一个水平面上所以这个投影一定是。。若干个圆再加上这些圆的边界这样组成的

  额或者说是这样:

  就是一些圆和相邻圆的切线组成的边界

  然后因为这个是。。一段连续的曲线嘛然后的话浮动应该不会太太太太大所以有一种相对简单的方法就是用Simpson积分直接爆搞(虽然说。。如果你特意构造一下数据的话还是可能会被卡掉的qwq)

  

  注意到这个图形是对称的所以我们可以先只看一半,然后最后输出的时候乘\(2\)就好了

​  然后这个边界的话我们可以将它看成一个函数\(f\),如果要用Simpson积分的话我们需要快速求这个函数在某个点的取值,我们记当前查询\(f(x)\),那么这个可以分成两种情况:

​  1、点\((x,f(x))\)在某个圆上,这种时候\(f(x)=\sqrt {r^2-(x-x_O)^2}\),其中\(x_O\)是这个圆的圆心的横坐标,\(r\)是这个圆的半径

​  2、点\((x,f(x))\)在某条切线上,那这个时候直接把\(x\)带进这条切线的解析式里面就可以得到\(f(x)\)了

  然而实际上在实现的时候,并不需要特别分类讨论,只要返回两种算的方法的最大值就好了

  

  

  那么剩下来的问题,就是如何求两个圆的切线

​  首先我们需要预处理一下,把被包含的圆去掉

  然后接下来我们只讨论不包含的情况

  还是用回这张图,我们只看\(x\)轴的上半部分

​  其中\(A,B\)均为切点,记\(l_{AB}\)与\(x\)轴的夹角为\(\theta\),\(L=O_1O_2\),第一个圆的半径为\(r\),第二个圆的半径为\(R\)

  由相似我们可以得到\(sin\theta=\frac{R-r}{L}\),进而我们可以得到\(cos\theta\)

  然后知道了\(sin\theta\)和\(cos\theta\)之后,我们就可以知道\(A\)和\(B\)的坐标了:

\[\begin{aligned}
A&=(x_{O_1}-sin\theta\cdot r,cos\theta \cdot r)\\
B&=(x_{O_2}-sin\theta\cdot R,cos\theta\cdot R)\\
\end{aligned}
\]

  然后我们就可以直接求一下\(l_{AB}\)的解析式了,这里不需要担心\(l_{AB}\)的斜率是否存在,因为这个图形保证了不会出现这种情况

  然后就很愉快滴做完啦ovo

  

  代码大概长这个样子(额貌似eps要开到1e-6才不会出锅qwq):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=510;
const double eps=1e-6,inf=2147483647;
double h[N],r[N],O[N],k[N],b[N];
double lx[N],rx[N],ly[N],ry[N];
int have[N];
int n,m;
double alpha,L,R;
double val(double x);
double simpson(double l,double r);
void prework();
void calc(int x);
bool in(int x,int y){return fabs(O[x]-O[y])<=fabs(r[x]-r[y]);}
double sqr(double x){return x*x;}
double solve(double l,double r); int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%d%lf\n",&n,&alpha);
++n;
for (int i=1;i<=n;++i){
scanf("%lf",h+i);
O[i]=h[i]/tan(alpha)+O[i-1];
}
L=inf,R=-inf;
for (int i=1;i<n;++i) scanf("%lf",r+i);
for (int i=1;i<=n;++i)
L=min(O[i]-r[i],L),R=max(O[i]+r[i],R); prework(); printf("%.2lf\n",solve(L,R)*2.0);
} double solve(double l,double r){
double mid=(l+r)*0.5,h=simpson(l,r),hmid=simpson(l,mid)+simpson(mid,r);
if (fabs(r-l)<=eps||(fabs(h-hmid)<=eps)) return hmid;
return solve(l,mid)+solve(mid,r);
} double simpson(double l,double r){
double hl=val(l),hr=val(r),hmid=val((l+r)*0.5);
return (r-l)*(hl+hr+hmid*4.0)/6.0;
} double val(double x){
double ret=0;
for (int i=1;i<=n;++i)
if (fabs(x-O[i])<=r[i])
ret=max(ret,sqrt(sqr(r[i])-sqr(x-O[i])));
for (int i=1;i<n;++i){
if (have[i]) continue;
if (lx[i]<=x&&x<=rx[i])
ret=max(ret,k[i]*x+b[i]);
}
return ret;
} void prework(){
for (int i=1;i<n;++i){
have[i]=in(i,i+1);
if (have[i]) continue;
calc(i);
}
} void calc(int x){
double l=(O[x+1]-O[x]);
double theta=asin((r[x+1]-r[x])/l);
double x1,y1,x2,y2;
x1=O[x]-sin(theta)*r[x]; y1=cos(theta)*r[x];
x2=O[x+1]-sin(theta)*r[x+1]; y2=cos(theta)*r[x+1];
lx[x]=x1; ly[x]=y1;
rx[x]=x2; ry[x]=y2; k[x]=(y2-y1)/(x2-x1);
b[x]=y1-k[x]*x1;
}

【bzoj1502】月下柠檬树的更多相关文章

  1. [BZOJ1502]月下柠檬树(自适应辛普森积分)

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

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

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

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

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

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

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

  5. [NOI2005]月下柠檬树[计算几何(simpson)]

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

  6. 【bzoj 1502】月下柠檬树

    月下柠檬树 题意 求n个圆与他们的公切线的定积分. 解法 求出圆的公切线就可以了. 特别坑的一点 : 最两端的圆,有可能会被其他的圆所包含,所以要重新求一下最左端与最右端. 比较坑的一点 : 精度要设 ...

  7. [NOI2005]月下柠檬树

    题意 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser  autoint Logout 捐赠本站 Probl ...

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

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

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

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

  10. BZOJ1502:[NOI2005]月下柠檬树——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1502 https://www.luogu.org/problemnew/show/P4207 李哲 ...

随机推荐

  1. selenium webdriver API详解(二)

    本系列主要讲解webdriver常用的API使用方法(注意:使用前请确认环境是否安装成功,浏览器驱动是否与谷歌浏览器版本对应) 一:获取当前页面的title(一般获取title用于断言) from s ...

  2. 8个数据清洗Python代码,复制可用,最长11行 | 资源

    最近,大数据工程师Kin Lim Lee在Medium上发表了一篇文章,介绍了8个用于数据清洗的Python代码. 数据清洗,是进行数据分析和使用数据训练模型的必经之路,也是最耗费数据科学家/程序员精 ...

  3. nginx启动、停止重启

    启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 例如: [root@LinuxServer sbin]# /usr/local/nginx/sbin/nginx -c /us ...

  4. Python os.makedirs() 方法

    os.makedirs() 方法用于递归创建目录.像 mkdir(), 但创建的所有intermediate-level文件夹需要包含子目录. 语法 makedirs()方法语法格式如下: os.ma ...

  5. Apriori 获取关联规则实现

    前言 自己的一个Apriori 获取关联规则的python实现.具体原理不讲,代码添加了说明,还是很好理解的. 数据预处理 #最小置信度 min_conf = 0.5 #最小支持度 min_sup = ...

  6. Cross origin requests are only supported for protocol schemes: http, data, chrome,chrome-extension的问题

    Cross origin requests are only supported for protocol schemes: http, data, chrome,chrome-extension的问 ...

  7. 作业三C++

    作业心得 1.本次作业开始使用C++编写了(面向过程的C++,2333) 2.粗略学习了一下文件输入输出,和项目的创建等(在大佬眼里最基本的操作QAQ,然而我还是有点晕晕的,平时都是ctrl+n新建源 ...

  8. 博弈---巴什博奕(Bash Game)(博弈入门)

    巴什博奕(Bash Game):只有一堆n个物品,两个人轮流从这堆物品中取物,规 定每次至少取一个,最多取m个.最后取光者得胜. 显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走 ...

  9. HDU 5159 Card

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5159 题解: 考虑没一个数的贡献,一个数一次都不出现的次数是(x-1)^b,而总的排列次数是x^b, ...

  10. C语言的知识与能力的自评

    1.我希望将来上班的地方是自己所感兴趣的,正在寻找自己感兴趣的,并且正在普及IT行业的相关知识. 2.我认为学习就是一个自我成长和自我提升以及认识世界的方法,学习的作用是可以不断的提升对这个世界的认识 ...