容易发现,圆锥体积和点的具体x、y坐标无关,只与其到z轴的距离sqrt(x*x+y*y)有关。

于是将这些三维的点都投射到二维的xOy平面的第二象限(sqrt(x*x+y*y),z),求个上凸壳,然后在每一点处,圆锥的母线的斜率的取值范围就确定了,发现这个圆锥的体积关于圆锥母线的函数是单峰的,可以三分。

于是枚举凸壳上每一个点,做个三分就行了。

#include<cstdio>
#include<cmath>
#include<algorithm>
#define EPS 0.00000001
using namespace std;
struct Point{
double x,y;
};
typedef Point Vector;
Vector operator - (const Point &a,const Point &b){
return (Vector){a.x-b.x,a.y-b.y};
}
double Cross(const Vector &a,const Vector &b){
return a.x*b.y-a.y*b.x;
}
bool cmp(const Point &a,const Point &b){
return fabs(a.x-b.x)>=EPS ? a.x<b.x : a.y<b.y;
}
int n,e;
Point ps[10010],qs[10010];
double V=10000000000000.0,R,H;
double sqr(double x){
return x*x;
}
double f(int K,double x){
return sqr(qs[K].y/x-qs[K].x)*(-qs[K].x*x+qs[K].y);
}
int main()
{
freopen("dome.in","r",stdin);
freopen("dome.out","w",stdout);
double X,Y,Z,maxZ=0,maxXY=0;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%lf%lf%lf",&X,&Y,&Z);
ps[i]=(Point){-sqrt(X*X+Y*Y),Z};
maxZ=max(maxZ,Z);
maxXY=max(maxXY,sqrt(X*X+Y*Y));
}
ps[n++]=(Point){0,maxZ};
ps[n++]=(Point){-maxXY,0};
sort(ps,ps+n,cmp);
for(int i=n-1;i>=0;--i){
while(e>1 && Cross(qs[e-1]-qs[e-2],ps[i]-qs[e-1])<EPS){
--e;
}
qs[e++]=ps[i];
}
for(int i=1;i<e-1;++i){
double l=(qs[i-1].y-qs[i].y)/(qs[i-1].x-qs[i].x),r;
if(fabs(l)<EPS){
l+=EPS;
}
if(fabs(qs[i].x-qs[i+1].x)>=EPS){
r=(qs[i].y-qs[i+1].y)/(qs[i].x-qs[i+1].x);
}
else{
r=10000000000000.0;
}
while(r-l>EPS){
double m1=(l+(r-l)/3.0);
double m2=(r-(r-l)/3.0);
// printf("%lf %lf\n",f(i,m1),f(i,m2));
// puts("");
if(f(i,m1)>f(i,m2)){
l=m1;
}
else{
r=m2;
}
// printf("%lf %lf\n",l,r);
}
double fl=f(i,l);
if(fl<V){
V=fl;
R=qs[i].y/l-qs[i].x;
H=-qs[i].x*l+qs[i].y;
}
}
printf("%.3f %.3f\n",H,R);
return 0;
}

【凸包】【三分】Gym - 101309D - Dome of Circus的更多相关文章

  1. bzoj 4311 向量 时间线建线段树+凸包+三分

    题目大意 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 3.查询当前集合与(x,y)点积的最大值是多少.如果当前是空集输出0 分析 按时间线建线段树 大致 ...

  2. bzoj 3533 [Sdoi2014]向量集 线段树+凸包+三分(+动态开数组) 好题

    题目大意 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); "Q x y l r (|x|,|y| & ...

  3. UVa 1473 - Dome of Circus 三分

    把所有的点都映射到XOZ这个平面的第一象限内,则这个三维问题可以转化二维问题: 求一条直线,使所有点在这条直线的下方,直线与X轴和Z轴围成的三角形旋转形成的圆锥体积最小. 这样转化之后可以看出直线的临 ...

  4. BZOJ3533 [Sdoi2014]向量集 【线段树 + 凸包 + 三分】

    题目链接 BZOJ3533 题解 我们设询问的向量为\((x_0,y_0)\),参与乘积的向量为\((x,y)\) 则有 \[ \begin{aligned} ans &= x_0x + y_ ...

  5. bzoj 2961 共点圆 cdq+凸包+三分

    题目大意 两种操作 1)插入一个过原点的圆 2)询问一个点是否在所有的圆中 分析 在圆中则在半径范围内 设圆心 \(x,y\) 查询点\(x_0,y_0\) 则\(\sqrt{(x-x_0)^2+(y ...

  6. bzoj 3203 凸包+三分

    题目大意 具体自己看吧link 读入n,D,表示n关 大概就是第i关有i只僵尸排成一队来打出题人 最前面那只是编号为\(i\)的僵尸,最后面的一只是编号为\(1\)的僵尸 最前面的僵尸离出题人\(X_ ...

  7. HDU 3756 Dome of Circus

    不会做,参见别人的程序: /* 底面为xy平面和轴为z轴的圆锥,给定一些点,使得圆锥覆盖所有点并且体积最小 点都可以投射到xz平面,问题转换为确定一条直线(交x,z与正半轴)使得与x的截距r 和与z轴 ...

  8. [BZOJ4311]向量(凸包+三分+线段树分治)

    可以发现答案一定在所有向量终点形成的上凸壳上,于是在上凸壳上三分即可. 对于删除操作,相当于每个向量有一个作用区间,线段树分治即可.$O(n\log^2 n)$ 同时可以发现,当询问按斜率排序后,每个 ...

  9. 【计算几何】【凸包】Gym - 101164H - Pub crawl

    平面上n个点,点之间沿直线走,规划一条路线,每次只能往左半平面的点走,走过最多的点. 显然所有的点都能走过. n^2的暴力显然是每次找左边与其所形成夹角最小的点,但这样过不了(卡常数?). 或者每轮不 ...

随机推荐

  1. Python中的异常处理 -- (转)

    python中的异常   异常是指程序中的例外,违例情况.异常机制是指程序出现错误后,程序的处理方法.当出现错误后,程序的执行流程发生改变,程序的控制权转移到异常处理. Exception类是常用的异 ...

  2. javascript中break和continue

    1.break break语句会立即退出循环,强制执行循环后面的语句 var num = 0; for(var i=1;i<10;i++){ if(i%5 == 0){ break; } num ...

  3. 史诗级Java/JavaWeb学习资源免费分享

    黑马内部视频+相关配套学习资料 Java Spring 技术栈构建前后台团购网站 Java SSM开发大众点评后端 欢迎关注微信公众号:Java面试通关手册 回复关键词: "资源分享第一波& ...

  4. LCD实验学习笔记(九):UART

    s3c2440包含三个通用异步收发器,可工作于中断模式或DMA模式.每个UART包含两个64字节的FIFOs用于接收和发送数据.可编程设置波特率.1或2个停止位,5/6/7/8个数据位和奇偶校验状态. ...

  5. vuejs怎么在服务器部署?

    通过npm run build 把生成的dist文件夹(不要上传文件夹)里的内容上传到http服务器上就可以通过 http来访问了,开发机上正常,上传以后 程序出现错误不能运行的原因99.99%的可能 ...

  6. Python3 生成器

    生成器(genetor): 1>生成器只有在调用的时候才会生成相应的数据: 2>生成器只记录当前位置,有一个__next__()方法 3>yield可以实现单线程先的并发运算 1.列 ...

  7. JS中的日期内置函数

    用JS中的日期内置函数实现在页面显示:“今天是:2013年9月26日14:32:45”. var date=new Date(Date.parse('9/26/2013 14:32:45'));   ...

  8. 增大dma的分配

    前言 项目中需要通过驱动与fpga通讯,获取fpga往内存里写的数据.因为数据量比较大,需要驱动分配600多M的内存给fpga来写数据,且因为是与fpga通讯,需要连续的内存,还得是uncached的 ...

  9. 自动化测试===Macaca环境搭建,自我总结

    安装jdk 安装安卓sdk(打开sdk的时候出现问题linux===启动sdk manager下载配置sdk的时候报错的解决办法) 安装gradle,配置环境变量(MACACA===gradle下载和 ...

  10. 【bzoj4486】【JSOI2015】串分割

    老省选题了. 首先考虑怎么比较超长数字的大小? 参见UTR1的那道题 先比size,然后比较字典序即可. 接下来考虑下切割的问题. 因为要将字符串切割成k份,所以这个字符串只会存在n/k个本质不同的起 ...