题意是三维空间上有一点集{a1,a2...an},每个点 ai 有一个参数 pi,现在要找到一点 t
使得所有形如 (|t.x - ai.x| +|t.y - ai.y| + |t.z - ai.z|)/pi 的值最大的最小
b_merry的做法:
1 #include <string>
2 #include <vector>
3 #include <map>
4 #include <cstdlib>
5 #include <cstring>
6 #include <cassert>
7 #include <set>
8 #include <iostream>
9 #include <sstream>
10 #include <cstddef>
11 #include <algorithm>
12 #include <utility>
13 #include <iterator>
14 #include <numeric>
15 #include <list>
16 #include <complex>
17 #include <cstdio>
18
19 using namespace std;
20
21 typedef vector<int> vi;
22 typedef vector<string> vs;
23 typedef long long ll;
24 typedef complex<double> pnt;
25 typedef pair<int, int> pii;
26
27 #define RA(x) (x).begin(), (x).end()
28 #define FE(i, x) for (typeof((x).begin()) i = (x).begin(); i != (x).end(); i++)
29 #define SZ(x) ((int) (x).size())
30
31 template<class T>
32 void splitstr(const string &s, vector<T> &out)
33 {
34 istringstream in(s);
35 out.clear();
36 copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
37 }
38
39 template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
40
41 struct ship
42 {
43 double xyz[3];
44 double p;
45 };
46
47 static bool reached(double q, const vector<ship> &ships)
48 {
49 /*如果要满足最小的q,那ships必定散落在四面八方,否则就不是最小
50 这样就有四个 关于x , y, z 的约束不等式 */
51 int delta[3][4] =
52 {
53 {1, 1, 1, 1},
54 {-1, -1, 1, 1},
55 {-1, 1, -1, 1}
56 };
57 int N = ships.size();
58 double range[4][2];
59 for (int i = 0; i < 4; i++)
60 {
61 range[i][0] = -HUGE_VAL;
62 range[i][1] = HUGE_VAL;
63 }
64 for (int i = 0; i < N; i++)
65 {
66 for (int a = 0; a < 4; a++)
67 {
68 double m =
69 delta[0][a] * ships[i].xyz[0]
70 + delta[1][a] * ships[i].xyz[1]
71 + delta[2][a] * ships[i].xyz[2];
72 range[a][0] = max(range[a][0], m - q * ships[i].p);
73 range[a][1] = min(range[a][1], m + q * ships[i].p);//求形如x * y * z的范围,*代表加或减
74 }
75 }
76 for (int a = 0; a < 4; a++)
77 {
78 if (range[a][0] > range[a][1])
79 return false;
80 }
81
82 bool low = false, high = false;
83 for (int v = 0; v < 8; v++)
84 {
85 double x_y_z = (v & 1) ? range[0][1] : range[0][0]; // (x-y-z)的范围
86 double x_yz = (v & 2) ? range[1][1] : range[1][0]; // (x -y+z)的范围
87 double xy_z = (v & 4) ? range[2][1] : range[2][0];// (x+y-z)的范围
88 /* 三个约束方程,又有三个未知数,所以单独每个成立的话,他们就成立了,
89 这三个约束不等式,再并上第四个如果有交集,就说明存在继续缩小的可能
90 */
91 double xyz = x_yz + xy_z - x_y_z; //(x+y+z)的范围
92 if (xyz >= range[3][0] && xyz <= range[3][1])//第四个约束条件范围更大
93 return true;
94 else if (xyz < range[3][0])
95 low = true;
96 else
97 high = true;
98 }
99 return low && high;//第四个约束条件范围更小
100 }
101
102 int main()
103 {
104 int cases;
105 cin >> cases;
106 for (int cas = 0; cas < cases; cas++)
107 {
108 int N;
109 cin >> N;
110 vector<ship> ships(N);
111 for (int i = 0; i < N; i++)
112 cin >> ships[i].xyz[0]
113 >> ships[i].xyz[1]
114 >> ships[i].xyz[2]
115 >> ships[i].p;
116 double l = 0.0;
117 double r = 1e9;
118 while (r - l > 1e-8 && r - l > 1e-8 * r)
119 {
120 double m = (l + r) * 0.5;
121 if (reached(m, ships))
122 r = m;
123 else
124 l = m;
125 }
126 printf("Case #%d: %.9f\n", cas + 1, l);
127 }
128 return 0;
129 }
130
posted on 2009-03-08 16:00
wangzhihao 阅读(159)
评论(0) 编辑 收藏 引用