Dome of Circus(三分)

Problem Description
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 1 ≤ i ≤ n 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 begins with an integer T. The next T blocks each represents a case. The first line of each case contains a single integer number n (1 ≤ n ≤ 10 000) - 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 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
3
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
 
Author
Georgiy Korneev
 
Source
2010 Northeastern European Regional Contest
 
Recommend
notonlysuccess

 实在无能为力了!!!!转的大牛的!!转自:http://www.naichagang.com/view/7Qe2K3Z5.html

这题需要用到三分法,首先说一下题意,就是给你一堆点的坐标,它们都在XOY平面或上方,求一个体积最小的锥,使这些点都在锥的表面上,输出锥的高度和半径。做法是这样的,首先我们要求的是一个锥的高度和半径,因此我们要将所有的点映射到第一卦限上面,然后转化为平面上的点,既转化为XOZ平面上的第一象限上的点,其中转化以后点的横坐标就是这点在锥上的半径。然后我们假设圆锥的底部半径就是r,那么可以根据数据的范围可以大概推算出r的范围,这一个范围就是三分的范围。然后可以分析得出无论是高度太大或者高度太小,圆锥的体积都会变大。我们的目标明显就是体积变化曲线的那个凹位。这就是为什么要使用三分的原因,三分可以在一段连续变化的曲线中找某个极值点,条件是这段曲线在极值的两端都是单调的。具体做法见代码,其中代码并不是最好的做法,可以继续优化三分的范围可以缩小位左边界是半径最大的那个点这样速度可以提高很多。

(表示不明白。。。。。。以后慢慢看QAQ)

代码:

#include <bits/stdc++.h>
#define max(x,y) (x > y ? x : y)
#define MAX 10000+10
const double eps=1e-7;
using namespace std;
struct point
 {
     double x,y,z;
     double r;
 };
 point p[MAX];
 int n;
 double ansv(double r)
 {
     int i;
     double h,tmp;
     h=0;     
	 for(i=0;i<n;i++)
     {
         tmp=p[i].z*r/(r-p[i].r);
         h=max(tmp,h);
     }
     return h;
 }
 void trisearch()
 {
     double L,R,mid,midl,midr,h;
     L=0;
     R=1000000.0;
     while(R-L>=eps)
     {
         mid=(L+R)/2;
         midl=(L+mid)/2;
         midr=(mid+R)/2;
        double hl=ansv(mid);
         double hr=ansv(midr);
         if(hl*mid*mid<hr*midr*midr) R=midr;
         else L=midl;     
		 }
     h=ansv(R);
     printf("%.3lf %.3lf\n",h,R);
 }
 int main()
 {
     int i,t;
     scanf("%d",&t);
     while(t--)
     {
         scanf("%d",&n);
         for(i=0;i<n;i++)
         {
             scanf("%lf %lf %lf",&p[i].x,&p[i].y,&p[i].z);
             p[i].r=sqrt(p[i].x*p[i].x+p[i].y*p[i].y);
         }
         trisearch();
   }
     return 0;
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值