【凸包】【三分】Gym - 101309D - Dome of Circus
容易发现,圆锥体积和点的具体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的更多相关文章
- bzoj 4311 向量 时间线建线段树+凸包+三分
题目大意 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 3.查询当前集合与(x,y)点积的最大值是多少.如果当前是空集输出0 分析 按时间线建线段树 大致 ...
- bzoj 3533 [Sdoi2014]向量集 线段树+凸包+三分(+动态开数组) 好题
题目大意 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); "Q x y l r (|x|,|y| & ...
- UVa 1473 - Dome of Circus 三分
把所有的点都映射到XOZ这个平面的第一象限内,则这个三维问题可以转化二维问题: 求一条直线,使所有点在这条直线的下方,直线与X轴和Z轴围成的三角形旋转形成的圆锥体积最小. 这样转化之后可以看出直线的临 ...
- BZOJ3533 [Sdoi2014]向量集 【线段树 + 凸包 + 三分】
题目链接 BZOJ3533 题解 我们设询问的向量为\((x_0,y_0)\),参与乘积的向量为\((x,y)\) 则有 \[ \begin{aligned} ans &= x_0x + y_ ...
- bzoj 2961 共点圆 cdq+凸包+三分
题目大意 两种操作 1)插入一个过原点的圆 2)询问一个点是否在所有的圆中 分析 在圆中则在半径范围内 设圆心 \(x,y\) 查询点\(x_0,y_0\) 则\(\sqrt{(x-x_0)^2+(y ...
- bzoj 3203 凸包+三分
题目大意 具体自己看吧link 读入n,D,表示n关 大概就是第i关有i只僵尸排成一队来打出题人 最前面那只是编号为\(i\)的僵尸,最后面的一只是编号为\(1\)的僵尸 最前面的僵尸离出题人\(X_ ...
- HDU 3756 Dome of Circus
不会做,参见别人的程序: /* 底面为xy平面和轴为z轴的圆锥,给定一些点,使得圆锥覆盖所有点并且体积最小 点都可以投射到xz平面,问题转换为确定一条直线(交x,z与正半轴)使得与x的截距r 和与z轴 ...
- [BZOJ4311]向量(凸包+三分+线段树分治)
可以发现答案一定在所有向量终点形成的上凸壳上,于是在上凸壳上三分即可. 对于删除操作,相当于每个向量有一个作用区间,线段树分治即可.$O(n\log^2 n)$ 同时可以发现,当询问按斜率排序后,每个 ...
- 【计算几何】【凸包】Gym - 101164H - Pub crawl
平面上n个点,点之间沿直线走,规划一条路线,每次只能往左半平面的点走,走过最多的点. 显然所有的点都能走过. n^2的暴力显然是每次找左边与其所形成夹角最小的点,但这样过不了(卡常数?). 或者每轮不 ...
随机推荐
- Tornado 安装及简单程序示例
1.安装步骤:tar xvzf tornado-3.2.tar.gz cd tornado-3.2 python setup.py build sudo python setup.py install ...
- ie8下a标签中的图片出现边框
1.ie8下a标签中的图片出现边框 <a href="#"><img src="horse.jpg"></a> 效果如图所示 ...
- Quartz的Properties文件解析
将可变信息放在properties文件是使配置更加灵活. 1.文档位置和加载顺序 1. StdSchedulerFactory默认加载quartz包下的quartz.properties文件,如果我们 ...
- Linux实际用户(组)ID,有效用户(组)ID,设置用户(组)ID
实际用户(组)ID: 标识用户是谁,这两个字段在登录时取自口令文件中的登录项. 有效用户(组)ID: 决定了对文件的访问权限,通常有效用户(组)ID等于实际用户(组)ID,谁运行有效ID就等于谁的实际 ...
- Linux进程的创建函数fork()及其fork内核实现解析
进程的创建之fork() Linux系统下,进程可以调用fork函数来创建新的进程.调用进程为父进程,被创建的进程为子进程. fork函数的接口定义如下: #include <unistd.h& ...
- 64_k1
KoboDeluxe-0.5.1-22.fc26.x86_64.rpm 13-Feb-2017 22:11 1626454 k3b-17.04.1-1.fc26.x86_64.rpm 25-May-2 ...
- [How to] 真机调试
1.简介 真机调试介绍. 在xcode7之前需要每年99刀的代价才能活着开发者权限并能够在真机上调试,现在如果单纯的想在真机上调是就不必花这个钱了. 2.步骤 完毕.
- 刷题中熟悉Shell命令之Tenth Line和Transpose File [leetcode]
首先介绍题目中要用的4个Shell命令 sed awk head tail的常用方法.(打好地基,才能建成高楼!) sed:(转自:http://www.cnblogs.com/barrychiao/ ...
- 17:django Email
我自己在看这一节之前自己先实现了一下,django-admin.py startproject testEmail新建一个新项目,urls.py把urlpatterns的第一行取消注释,改成url(r ...
- classpath中怎样一次性加入整个目录的jar文件
linux可以通过shell来处理 1 2 3 for jar in $HOME/lib/*.jar; do CLASSPATH=$CLASSPATH:$jar done