您的位置:首页 > 其它

hdu 3756 Dome of Circus(三分)

2013-02-27 12:31 211 查看
题意:求能将所有点覆盖的最小体积的圆锥。

体积变化为凹形,故可以三分半径r,再枚举各个点找最大的高h。

View Code

/*
Author:Zhaofa Fang
Lang:C++
*/
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef long long ll;
#define DEBUG(x) cout<< #x << ':' << x << endl
#define REP(i,n) for(int i=0;i < (n);i++)
#define REPD(i,n) for(int i=(n-1);i >= 0;i--)
#define FOR(i,s,t) for(int i = (s);i <= (t);i++)
#define FORD(i,s,t) for(int i = (s);i >= (t);i--)
#define PII pair<int,int>
#define PB push_back
#define MP make_pair
#define ft first
#define sd second
#define lowbit(x) (x&(-x))
#define INF (1<<30)

const double PI = 3.1415926;
int n;
struct point
{
double x,y,z;
}P[10005];
double volume(double r,double h)
{
return PI*r*r*h/3.0;
}

double fun(double r,double &hx)
{
double MAX = 0;
REP(i,n)
{
double h = P[i].z*r/(r-sqrt(P[i].x*P[i].x+P[i].y*P[i].y));
MAX = max(MAX,h);
}
hx = MAX;
return volume(r,MAX);
}
int main()
{
//freopen("in","r",stdin);
//freopen("out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
double M=0;
REP(i,n)
{
scanf("%lf%lf%lf",&P[i].x,&P[i].y,&P[i].z);
M = max(M,sqrt(P[i].x*P[i].x+P[i].y*P[i].y));
}
double l=M+1e-6,r=100000.0,hx;
while(fabs(l-r) > 1e-6)
{
double lm = l + (r-l)/3.0;
double rm = r - (r-l)/3.0;
if(fun(lm,hx)<fun(rm,hx))r = rm;
else l = lm;
}
printf("%.3f %.3f\n",hx,r);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: