hdu 3756

三分


首先三维变二维


L这条线必定和某一
个给定的点擦边,也就是经过那个点,我们假设它经过P(a, b), 并且L的斜率
为K(K < 0),那么L的方程就可以表示为 L:  y = K * (x - a) + b,则H和R就
可以利用这个方程表示出来:


H = -a * K + b;
R = -b / K + a;


那么所求的圆锥的体积就是:


V = pi*H*R^2 = pi * (-a * K + b) * (-b / K + a) ^ 2


容易得到V(K)这个函数的导数:
V'(K) = - pi * (aK^2 + 2bK) * (aK - b)^2 / K^2


影响这个导数的正负性的唯一条件是 -(aK^2 + 2bK)


当-2b/a < K < 0时V'(K)大于零,也就是V的值是随着K递增的。
当K < -2b/a时V'(K)小于零,也就是V的值是随着K递减的。
于是可以得出一个结论,当K = -2b/a 时V取得最小值。
于是我们知道了V的单峰性,然后就可以通过枚举半径R,因为R对于V具有单谷
性,所以枚举R的时候可以采用三分。每次通过三分R找到最小的H,这个过程可
以通过枚举每个点,找到最大的极角alpha,R*tan(alpha)就是H了。

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <iterator>
#include <cmath>
#include <deque>
#include <stack>
#include <cctype>
#include <iomanip>
using namespace std;

typedef long long ll;
typedef long double ld;

const int N = 10;
const int INF = 0xfffffff;
const double EPS = 1e-8;
const ll MOD = 1e9 + 7;
const ld PI = acos (-1.0);

#define INFL 0x7fffffffffffffffLL
#define met(a, b) memset(a, b, sizeof(a))
#define rep(c, a, b) for (int c = a; c < b; c++)
#define nre(c, a, b) for (int c = a; c > b; c--)
#define put(a) cout << setiosflags(ios::fixed) << setprecision(a)

struct point
{
    double x, y, z, r;
};

vector <point> a;

double cot (double R);

int main ()
{
    int n, t;
    scanf ("%d", &t);
    while (t--)
    {
        scanf ("%d", &n);
        a.clear();
        double ll = 0;
        rep (i, 0, n)
        {
            double tx, ty, tz;
            scanf ("%lf%lf%lf", &tx, &ty, &tz);
            a.push_back ({tx, ty, tz, sqrt(tx*tx+ty*ty)});
            ll = max (ll, sqrt(tx*tx+ty*ty));
        }
        double l = ll, r = ll*3, lm, rm;
        while (r - l > EPS)
        {
            lm = (l + r) / 2;
            rm = (lm + r) / 2;
            if (cot(lm) * lm * lm < cot(rm) * rm * rm) r = rm;
            else l = lm;
        }
        printf ("%.3lf %.3lf\n", cot(lm), lm);
    }
    return 0;
}

double cot (double R)
{
    double h = 0;
    rep (i, 0, a.size())
        h = max (a[i].z / (R  - a[i].r), h);
    return h * R;
}

cin居然超时 用流读入加速也不行 看来流读入加速真的不给力啊


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值