[THOJ 1589] 椭球面 三分套三分

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[THOJ 1589] 椭球面 三分套三分相关的知识,希望对你有一定的参考价值。

题意

  现在给出一个椭球面: $ax ^ 2 + by ^ 2 + cz ^ 2 + dyz + exz + fxy = 1$ .

  求椭球面到 $(0, 0, 0)$ 的距离.

  $T \le 200, 0 < a, b, c < 1, 0 \le d, e, f < 1$ .

  假装 $(0, 0, 0)$ 在椭球内部.

 

分析

  二次的式子通常都是单峰的.

  猜测椭球到 $(0, 0, 0)$ 的距离也是单峰的.

  三分 x , 三分 y , 利用一元二次方程解出 z 并计算距离.

 

实现

  实现小结:

    1. 对于三分, 模拟退火之类的, 最好记录访问到的最大的答案, 而不是最后再求一次.

    2. 浮点数上, 如果运算出错, 会返回 nan , 判断一个数是不是 nan , 就判断 !(x < 0) && !(x >= 0) .

 

  最终实现:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 9 #define db double
10 
11 const db INF = 1e30;
12 
13 db a, b, c, d, e, f, ans;
14 
15 inline bool nan(db x) { return !(x < 0) && !(x >= 0); }
16 inline db Dist(db x, db y, db z) { return sqrt(x * x + y * y + z * z); }
17 inline db Calc(db x, db y) {
18     db A = c;
19     db B = d * y + e * x;
20     db C = a * x * x + b * y * y + f * x * y - 1;
21     db D = B * B - 4 * A * C;
22     db z = (-B - sqrt(D)) / (2 * A);
23     db tmp = Dist(x, y, z);
24     return ans = min(ans, tmp), tmp;
25 }
26 inline db Y(db x) {
27     db l = 0, r = 1000 / sqrt(b);
28     while (r-l > 1e-10) {
29         db _l = (l+l+r)/3, ansL = Calc(x, _l);
30         db _r = (l+r+r)/3, ansR = Calc(x, _r);
31         nan(ansL) || nan(ansR) || ansL < ansR ? r = _r : l = _l;
32     }
33     db ans = Calc(x, l);
34     
35     l = -1000 / sqrt(b), r = 0;
36     while (r-l > 1e-10) {
37         db _l = (l+l+r)/3, ansL = Calc(x, _l);
38         db _r = (l+r+r)/3, ansR = Calc(x, _r);
39         nan(ansL) || nan(ansR) || ansR < ansL ? l = _l : r = _r;
40     }
41     db ans2 = Calc(x, l);
42     
43     return nan(ans) ? ans2 : nan(ans2) ? ans : min(ans, ans2);
44 }
45 inline db X(void) {
46     db l = 0, r = 1000 / sqrt(a);
47     while (r-l > 1e-10) {
48         db _l = (l+l+r)/3, ansL = Y(_l);
49         db _r = (l+r+r)/3, ansR = Y(_r);
50         nan(ansL) || nan(ansR) || ansL < ansR ? r = _r : l = _l;
51     }
52     db ans = Y(l);
53     
54     l = -1000 / sqrt(a), r = 0;
55     while (r-l > 1e-10) {
56         db _l = (l+l+r)/3, ansL = Y(_l);
57         db _r = (l+r+r)/3, ansR = Y(_r);
58         nan(ansL) || nan(ansR) || ansR < ansL ? l = _l : r = _r;
59     }
60     db ans2 = Y(l);
61     
62     return nan(ans) ? ans2 : nan(ans2) ? ans : min(ans, ans2);
63 }
64 
65 int main(void) {
66     #ifndef ONLINE_JUDGE
67         freopen("e.in", "r", stdin);
68     #endif
69     
70     while (~scanf("%lf %lf %lf %lf %lf %lf", &a, &b, &c, &d, &e, &f))
71         ans = INF, X(), printf("%0.8lf\n", ans);
72     
73     return 0;
74 }

 

以上是关于[THOJ 1589] 椭球面 三分套三分的主要内容,如果未能解决你的问题,请参考以下文章

D.Country Meow 最小球覆盖 三分套三分套三分 && 模拟退火

HDU3400 三分套三分

BZOJ 1857 传送带 | 三分套三分

bzoj1857传送带——三分套三分

盘点NBA三分球最准组合,水花齐上榜,这套阵容能拿总冠军么?

BZOJ1857: [Scoi2010]传送带(三分套三分)