UVA1473 - Dome of Circus

做了两天……终于搞定了

就是给你一些点,求能够包裹这些点体积最小的圆锥的底圆半径和圆锥的高

虽然网上很多用三分的方法写,不过好像是某电的课件做法,然后很多人跟风……

不管怎么说,我是用计算几何的方法写的

我的做法:

观察之后可以发现把一个点投影到xoy平面上跟原点的距离可以当作x对待,原来的z可以当作y对待,这样就转换成了二维

只需要在二维图中找一条线与x,y轴围住这些点就行了

想一想就会发现,这条线肯定经过一个点或者两个点,因为圆锥体相当于这条线围绕y轴旋转一周后形成

两个点能够唯一确定一条直线,那么一个点也可以确定一个体积最小的圆锥体,通过列表达式求导可以知道,r=1.5x,h=3y的时候满足

找一个右极点逆时针做凸包,逆时针爬到最高处即可遍历可能的情况

我的代码:

#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
struct ddot
{
	double x,y;
	ddot(){};
	ddot(double a,double b)
	{
		x=a;
		y=b;
	}
};
ddot operator -(ddot a,ddot b)
{
	return ddot(a.x-b.x,a.y-b.y);
}
double operator *(ddot a,ddot b)
{
	return a.x*b.y-b.x*a.y;
}
bool cmp(ddot a,ddot b)
{
	return a.x!=b.x?a.x>b.x:a.y>b.y;
}
ddot K;
double dis2(ddot a,ddot b)
{
	return pow(a.x-b.x,2)+pow(a.y-b.y,2);
}
bool cmp1(ddot a,ddot b)
{
	double t=(a-K)*(b-K);
	return t!=0?t>0:dis2(a,K)>dis2(b,K);
}
double ch(ddot a,ddot b)
{
	return (b.y*a.x-b.x*a.y)/(a.x-b.x);

}
double cr(ddot a,ddot b)
{
	return (b.y*a.x-b.x*a.y)/(b.y-a.y);
}
int main()
{
	int i,top,n,ymax;
	double x,y,z,h,r,t,low,high,vmin,hmin,rmin;
	ddot dot[10010],box[10010];
	while(cin>>n)
	{
		for(i=0;i<n;i++)
		{
			scanf("%lf%lf%lf",&x,&y,&z);
			dot[i].x=sqrt(x*x+y*y);
			dot[i].y=z;
		}
		sort(dot,dot+n,cmp);
		K=dot[0];
		sort(dot+1,dot+n,cmp1);
		box[0]=dot[0];box[1]=dot[1];
		top=1;
		for(i=2;i<n;)
		{
			t=(box[top]-box[top-1])*(dot[i]-box[top-1]);
			if(t>0)
				box[++top]=dot[i++];
			else if(t==0)
				i++;
			else
				top--;
		}
		ymax=0;
		for(i=0;i<=top;i++)
			if(box[i].y>box[ymax].y)
				ymax=i;
		vmin=1e99;
		for(i=0;i<=ymax;i++)
		{
			if(i==0)
				low=box[0].x;
			else
				low=cr(box[i],box[i-1]);
			if(i==ymax)
				high=1e99;
			else
				high=cr(box[i],box[i+1]);
			t=1.5*box[i].x;
			if(t<low)
			{
				r=low;
				h=ch(box[i],box[i-1]);
			}
			else if(t<=high)
			{
				r=t;
				h=box[i].y*3;
			}
			else
			{
				r=high;
				h=ch(box[i],box[i+1]);
			}
			t=r*r*h;
			if(t<vmin)
			{
				vmin=t;
				rmin=r;
				hmin=h;
			}
		}
		printf("%.3lf %.3lf\n",hmin,rmin);
	}
}

Time limit: 3.000 seconds

A travelling circus faces a tough challenge in designing the dome for its performances. The circus has a number of shows that happen above the stage in the air under the dome. Various rigs, supports, and anchors must be installed over the stage, but under
the dome. The dome itself must rise above the center of the stage and has a conical shape. The space under the dome must be air-conditioned, so the goal is to design the dome that contains minimal volume.

You are given a set of n points in the space;
(xi, yi, zi) for
1in
are the coordinates of the points in the air above the stage that must be covered by the dome. The ground is denoted by the plane
z = 0, with positive z coordinates going up. The center of the stage is on the ground at the point (0, 0, 0).

The tip of the dome must be located at some point with coordinates
(0, 0, h) with h > 0. The dome must have a conical shape that touches the ground at the circle with the center in the point (0, 0, 0) and with the radius of
r. The dome must contain or touch all the
n given points. The dome must have the minimal volume, given the above constraints.

Input

The input file contains several test cases, each of them as described below.

The first line of the input file contains a single integer number
n (1n10000)
-- the number of points under the dome. The following n lines describe points with three floating point numbers
xi, yi, and
zi per line -- the coordinates of
i-th point. All coordinates do not exceed 1000 by their absolute value and have at most 2 digits after decimal point. All
zi are positive. There is at least one point with non-zero
xi or yi.

Output

For each test case, write to the output file a single line with two floating point numbers
h and r -- the height and the base radius of the dome. The numbers must be precise up to 3 digits after decimal point.

Sample Input

1
1.00 0.00 1.00
2
1.00 0.00 1.00
0.00 1.50 0.50
3
1.00 0.00 1.00
0.00 1.50 0.50
-0.50 -0.50 1.00

Sample Output

3.000 1.500
2.000 2.000
2.000 2.000

时间: 2024-12-09 16:07:59

UVA1473 - Dome of Circus的相关文章

UVALive 4986 Dome of Circus(三分、凸包、凸性函数)

题目链接: UVALive 4986 Dome of Circus 题意: 在空间中给n个点的坐标,并且每个点都是在z轴的正半平面内,以原点(0,0,0)为底面圆圆心,画一个圆锥,要求圆锥要包含所有的点,点可以在圆锥面上,求最小的圆锥体积的底面圆半径和高. 数据范围:1≤n≤10000,并且所有点的坐标的绝对值都不超过10000 分析: 首先把三维的点转成二维的,因为是圆锥覆盖,所以我们只需要知道点到圆锥轴的距离和点的纵坐标就好了.那么可得: (x,y,z)→(x2+y2??????√,z) 这

几何基础专题

UVA 11437 Triangle Fun UVA 11800 Determine the Shape 四边形判定 UVA 11646 Athletics Track UVA 11817 Tunnelling the Earth 球面距离 UVA 1473 Dome of Circus UVA 11524 InCircle UVA 11731 Ex-circles 旁切圆 UVA 12300 Smallest Regular Polygon UVA 10566 Crossed Ladders

[UWP小白日记-2]SQLite数据库DOME

数据库说简单点就是增删改查,但是对新手来说也是要爆肝的.作为一个新手爆肝无数次啊, 血的教训啊现在UWP的教程又少,说多了都是泪.留下来免得以后又爆肝.还有:一定要写注释!一定要写注释!一定要写注释! 重要的事情说三遍! 1.首先,准备工作: 1)引用: 获取途径:VS里的扩展和更新.NuGet等. 2)数据库模型: 1 internal class ACCOURT 2 { 3 public ACCOURT() { } //空构造函数 4 public ACCOURT(int ID,double

iOS 搜索框控件 最简单的dome

刚学习搜索框控件,写了个最简单的dome #import <UIKit/UIKit.h> .h @interface ViewController : UIViewController<UISearchBarDelegate,UISearchDisplayDelegate,UITableViewDataSource,UITableViewDelegate> @property (nonatomic,strong) UISearchDisplayController *searchD

HDU 5515 Game of Flying Circus 二分

Game of Flying Circus Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5515 Description The discovery of anti-gravitations technology changed the world. The invention of anti-gravitation shoes (Grav-shoes) enable

Codeforces Beta Round #1 C. Ancient Berland Circus

果然Java还是不靠谱啊,一个NaN把我整了半天~~ 题目大意: 有一个正多边形,给出任意三个顶点的坐标,求这个正多边形的最小面积. 解题思路: 首先要知道这三个顶点组成的三角形的外接圆一定是这个正多边形的外接圆. 用过计算出三角形的三边长,可以计算出三角型面积,进而推出外接圆半径. 可以得到三个圆心角,找出最大公约数,那就是最大角度. 就可以计算出多边形面积了~~ 下面是代码: import java.text.DecimalFormat; import java.util.Scanner;

CodeForce-1C Ancient Berland Circus

Ancient Berland Circus Nowadays all circuses in Berland have a round arena with diameter 13 meters, but in the past things were different. In Ancient Berland arenas in circuses were shaped as a regular (equiangular) polygon, the size and the number o

Java反射机制DOME

Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName("testHibernate.Test1"); //classload 类 Object oj = cs.newInstance(); //通过类NEW一个对象 Method[] mt = cs.getMethods(); //获取所有方法 for (Method method : mt) {

ios 上拉加载下拉刷新Dome

为练手写了一个小的上拉加载更多下拉刷新的小的Dome . 没有太多的技术含量,只是作为新手的启发用.是上一篇下拉加载的扩展.先看一下那个再看这个就容易很多. Dome下载:http://download.csdn.net/detail/u010123208/8062715 先来梳理一下: 上拉家在更多就是上拉之后在底部现实一个视图,用来提示用户上拉加载更多,如果用户上拉就出发事件,进行加载并在试图中给予提示,同时后台加载数据,将添加的数据加入数据数组,最后重新导入列表: 下拉刷新同样的操作,只不