题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4573
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <cmath> 6 using namespace std; 7 typedef long long LL; 8 9 const int MAXN = 10001; 10 const double EPS = 1e-9; 11 12 inline int sgn(double x) { 13 return (x > EPS) - (x < -EPS); 14 } 15 16 struct Point { 17 double x, y, z; 18 Point() {} 19 Point(double x, double y, double z): x(x), y(y), z(z) {} 20 void read() { 21 scanf("%lf%lf%lf", &x, &y, &z); 22 } 23 Point operator - (const Point &rhs) const { 24 return Point(x - rhs.x, y - rhs.y, z - rhs.z); 25 } 26 double operator * (const Point &rhs) const { 27 return x * rhs.x + y * rhs.y + z * rhs.z; 28 } 29 }; 30 double length(const Point &a) { 31 return sqrt(a * a); 32 } 33 Point cross(const Point &a, const Point &b) { 34 Point res; 35 res.x = a.y * b.z - a.z * b.y; 36 res.y = a.z * b.x - a.x * b.z; 37 res.z = a.x * b.y - a.y * b.x; 38 return res; 39 } 40 Point cross(const Point &o, const Point &a, const Point &b) { 41 return cross(a - o, b - o); 42 } 43 double volume(const Point &a, const Point &b, const Point &c, const Point &d) { 44 return cross(c - a , b - a) * (d - a) / 6; 45 } 46 Point p[MAXN]; 47 48 struct Face { 49 int a, b, c; 50 bool flag; 51 Face() {} 52 Face(int a, int b, int c, bool flag): a(a), b(b), c(c), flag(flag) {} 53 bool can_see(const Point &q) { 54 return sgn(volume(p[a], p[b], p[c], q)) > 0; 55 } 56 }; 57 Face fac[MAXN * 10]; 58 59 struct Convex { 60 double diff_vol; 61 int cnt, mat[MAXN][MAXN]; 62 63 void init() { 64 cnt = 0; 65 for(int i = 0; i < 4; ++i) { 66 Face newf = Face((i + 1) % 4, (i + 2) % 4, (i + 3) % 4, true); 67 if(newf.can_see(p[i])) swap(newf.a, newf.c); 68 mat[newf.a][newf.b] = mat[newf.b][newf.c] = mat[newf.c][newf.a] = cnt; 69 fac[cnt++] = newf; 70 } 71 } 72 73 void restore(int k, int a, int b) { 74 int f = mat[a][b]; 75 if(fac[f].flag) { 76 if(fac[f].can_see(p[k])) dfs(k, f); 77 else { 78 mat[b][a] = mat[a][k] = mat[k][b] = cnt; 79 fac[cnt++] = Face(b, a, k, true); 80 } 81 } 82 } 83 84 void dfs(int k, int f) { 85 diff_vol += volume(p[fac[f].a], p[fac[f].b], p[fac[f].c], p[k]); 86 fac[f].flag = false; 87 restore(k, fac[f].b, fac[f].a); 88 restore(k, fac[f].c, fac[f].b); 89 restore(k, fac[f].a, fac[f].c); 90 } 91 92 double update(int k) { 93 diff_vol = 0; 94 for(int i = 0; i < cnt; ++i) { 95 if(!fac[i].flag || !fac[i].can_see(p[k])) continue; 96 dfs(k, i); 97 break; 98 } 99 return diff_vol; 100 } 101 102 double vol() { 103 double res = 0; 104 for(int i = 0; i < cnt; ++i) if(fac[i].flag) 105 res -= volume(p[fac[i].a], p[fac[i].b], p[fac[i].c], Point(0, 0, 0)); 106 return res; 107 } 108 } solver; 109 110 int n, kase; 111 112 void solve() { 113 int king = 0; 114 double maxans = 0; 115 for(int i = 1, tmp = 1; i < n; ++i) { 116 if(tmp == 1) { 117 tmp += sgn(length(p[0] - p[i])); 118 if(tmp > 1) swap(p[1], p[i]); 119 } else if(tmp == 2) { 120 tmp += sgn(length(cross(p[0], p[1], p[i]))); 121 if(tmp > 2) swap(p[2], p[i]); 122 } else if(tmp == 3) { 123 tmp += (sgn(volume(p[0], p[1], p[2], p[i])) != 0); 124 if(tmp > 3) { 125 swap(p[3], p[i]); 126 solver.init(); 127 for(int j = 4; j <= i; ++j) solver.update(j); 128 king = i, maxans = solver.vol(); 129 } 130 } else { 131 double v = solver.update(i); 132 if(sgn(v - maxans) > 0) { 133 maxans = v; 134 king = i; 135 } 136 } 137 } 138 printf("%d %.2f\n", king + 1, maxans); 139 } 140 141 int main() { 142 while(scanf("%d", &n) != EOF) { 143 for(int i = 0; i < n; ++i) p[i].read(); 144 printf("Case #%d:\n", ++kase); 145 solve(); 146 } 147 }