hdu 3756

来源:互联网 发布:市政工程计算软件 编辑:程序博客网 时间:2024/06/10 09:26

三分


首先三维变二维


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