随笔-21  评论-10  文章-21  trackbacks-0
题意是三维空间上有一点集{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<intint> 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         {1111},
 54         {-1-111},
 55         {-11-11}
 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 阅读(150) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理