您的位置:首页 > 其它

【三分】HDU3756 Dome of Circus

2015-09-09 20:03 357 查看
假设我们枚举一个半径rr,那么分别考虑包含进每个点圆锥的最小高度h0,h1,…,hn−1h_0,h_1,\dots,h_{n-1},显然此时如果半径为rr,圆锥高度应为maxn−1i=0 hi{max}_{i=0}^{n-1}\ h_i,简单推算一下公式,可以发现体积关于半径是个凹函数,于是三分半径即可。

注意初始的半径范围,上限自然可以随便设置一个较大值,但下限需要稍加考虑。设di=xi2+yi2−−−−−−−√{d}_i=\sqrt{{x_i}^2+{y_i}^2}那么rr应满足r>max{di},0≤i<nr\gt max\{{d}_i\},0\le i\lt n

输入输出部分,即使
ios::sync_with_stdio(false)
也无法避免
cin
cout
的超时问题,所以似乎必须用
printf
scanf
来IOIO。

/* **********************************************

File Name: 3756.cpp

Auther: zhengdongjian@tju.edu.cn

Created Time: 2015/9/9 星期三 下午 7:07:06

*********************************************** */
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
const double EPS = 1e-4;
const double INF = (double)INT_MAX;
const int MAX = 10007;
struct Pos {
double x, y, z;
} a[MAX];
int n;

istream& operator>>(istream& in, Pos& p) {
in >> p.x >> p.y >> p.z;
return in;
}

pair<double, double> gao(double r) {
double h = 0.0;
for (int i = 0; i < n; ++i) {
double dis = a[i].x * a[i].x + a[i].y * a[i].y;
dis = sqrt(dis);
//printf("dis = %f\n", dis);
//getchar();
double tp = a[i].z / (r - dis) * dis + a[i].z;
if (tp > h) h = tp;
}
return make_pair(h, r * r * h);
}

pair<double, double> cut(double le, double ri) {
double md, mdmd;
while (ri - le > EPS) {
//printf("le = %f, ri = %f\n", le, ri);
md = (le + ri) * 0.5;
mdmd = (md + ri) * 0.5;
if (gao(mdmd).second > gao(md).second) {
ri = mdmd;
} else {
le = md;
}
}
//printf("le = %f, ri = %f\n", le, ri);
return make_pair(gao(le).first, le);
}

int main() {
int T;
scanf(" %d", &T);
while (T--) {
scanf(" %d", &n);
double mindis = 0.0;
for (int i = 0; i < n; ++i) {
scanf(" %lf %lf %lf", &a[i].x, &a[i].y, &a[i].z);
mindis = min(mindis, sqrt(a[i].x * a[i].x + a[i].y * a[i].y));
}
//auto res = make_pair(0.0, 0.0);
auto res = cut(mindis + EPS, 100000.0);
printf("%.3f %.3f\n", res.first + EPS, res.second + EPS);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: