[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 }
时间: 2024-07-31 05:26:39

[THOJ 1589] 椭球面 三分套三分的相关文章

【bzoj1857】传送带——三分套三分

我的第一道三分题目. 早上跟着cyc学了一下三分,晚上想练一下手发现没什么水题就找到了这一道2333 主要是证明是一个单峰函数,这也是本题最难的部分(网上好多人写出来但不会证明:)) 证明过程来自yyl dalao: 本题要讨论必使r<max(q,p),否则还要走什么传送带... 从A点出发,要使解最优,必定要走A->E->F->D,其中E是AB上一点,F为CD上一点. 因为E和F都是不确定的,我们不妨假设E点已经确定,那么CD上必定存在一点F使得EF和FD最优(先不考虑AE),那

三分套三分 --- HDU 3400 Line belt

Line belt Problem's Link:    Mean: 给出两条平行的线段AB, CD,然后一个人在线段AB的A点出发,走向D点,其中,人在线段AB上的速度为P, 在线段CD上的速度为Q,在其他地方的速度为R,求人从A点到D点的最短时间. analyse: 经典的三分套三分. 首先在AB线段上三分,确定一个点,然后再在CD上三分,确定第二个点,计算出answer.也就是嵌套的三分搜索. Time complexity: O(logn*logm) Source code:  // M

hdu3400(三分套三分)

题意:平面上两条线段 AB,CD. A到B的速度v1,C到D的速度v2,其他地方的速度V3.求A到D的最短时间. 解法:三分嵌套三分,首先如果AB上的点确定后,确定CD的点的确定应该是符合三分性质的,应该是单调或最多凸型分布的.那么确定AB上的点,也应该不会出现多个峰谷吧.没有严格证明,是知道有个这个三分嵌套三分的题目才来做的. 代码: /****************************************************** * author:xiefubao ******

【BZOJ-1857】传送带 三分套三分

1857: [Scoi2010]传送带 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 1077  Solved: 575[Submit][Status][Discuss] Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R.现在lxhgww想从A点走到D点,他想知道最少需要走多长时间 Input 输入

BZOJ 1857 传送带 (三分套三分)

在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R.现在lxhgww想从A点走到D点,他想知道最少需要走多长时间 Input输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 第三行是3个整数,分别是P,Q,ROutput输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留

bzoj1857 [ SCOI2010 ] -- 三分套三分

显然我们一定是先走到AB上一点X,然后走到CD上一点Y,最后到D. 那么答案就是|AX|/P+|XY|/R+|YD|/Q 假设我们已经确定了X,那么目标就是在CD上找一点Y,使|XY|/R+|YD|/Q最小. 显然这是个单峰函数. 那么三分套三分就可以了. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> us

#10017 传送带(SCOI 2010)(三分套三分)

[题目描述] 在一个 2 维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段 AB 和线段 CD.lxhgww 在 AB上的移动速度为 P ,在 CD 上的移动速度为 Q,在平面上的移动速度 R.现在 lxhgww 想从 A 点走到 D 点,他想知道最少需要走多长时间. [题目链接] https://loj.ac/problem/10017 [算法] 猜想两条线段的最优点均满足单峰性质,于是三分套三分,代码借鉴黄学长.(http://hzwer.com/4255.html

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

// 2019.10.3 // 练习题:2018 ICPC 南京现场赛 D Country Meow 题目大意 给定空间内 N 个点,求某个点到 N 个点的距离最大值的最小值. ? 思路 非常裸的最小球覆盖问题啊,即找到半径最小的球包含全部的点. 在最小圆覆盖问题上,可以使用随机增量法,这里没有四点确定球心的公式,所以板子失效了. 最小圆覆盖可以用三分套三分,这里空间有三维,假装证明得到在任意一维上都满足凸函数特性,那么再套一层维度三分就OK了. ? AC代码 三分套三分套三分写法,复杂度O(n

HDU3400 三分套三分

题意 就是给你两条线段AB , CD ,一个人在AB以速度p跑,在CD上以q跑, 在其他地方跑速度是r.问你从A到D最少的时间. 三分AB ,然后再三分CD ,模板题目,这题卡精度 eps不能少 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <cmath> 5 #include <algorithm> 6 #include <set> 7