题目地址
这个是我照着lrj的蓝书打的。
代码
#include <bits/stdc++.h>
#define pb push_back
#define db double
#define N 2005
#define eps 1e-9
using namespace std;
bool vis[N][N];
db ans = 0;
db rand01() {return rand()/(db)RAND_MAX;}
db randeps() {return (rand01() - 0.5) * eps;}
struct Point3 {
db x, y, z;
Point3(db x = 0, db y = 0, db z = 0): x(x), y(y), z(z){}
}P[N];
typedef Point3 Vector3;
Vector3 operator +(Vector3 A, Vector3 B) {
return Vector3(A.x + B.x, A.y + B.y, A.z + B.z);
}
Vector3 operator -(Vector3 A, Vector3 B) {
return Vector3(A.x - B.x, A.y - B.y, A.z - B.z);
}
Vector3 operator *(Vector3 A, db p) {
return Vector3(A.x * p, A.y * p, A.z * p);
}
Vector3 operator /(Vector3 A, db p) {
return Vector3(A.x / p, A.y / p, A.z / p);
}
Vector3 Cross(Vector3 A, Vector3 B) {
return Vector3(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x);
}
db Dot(Vector3 A, Vector3 B) {return A.x * B.x + A.y * B.y + A.z * B.z;}
db Length(Vector3 A) {return sqrt(Dot(A, A));}
struct Face {
int v[3];
Vector3 normal(Point3 *P) const{
return Cross(P[v[1]] - P[v[0]], P[v[2]] - P[v[0]]);
}
int cansee(Point3 *P, int i) const {
return Dot(P[i] - P[v[0]], normal(P)) > 0 ? 1 : 0;
}
};
vector<Face> Ans;
vector<Face> CH3D(Point3 *P, int n) {
vector<Face> cur;
cur.clear();
cur.pb((Face){0, 1, 2});
cur.pb((Face){2, 1, 0});
for (int i = 3; i < n; i ++) {
vector<Face> nxt;
for (int j = 0; j < (int)cur.size(); j ++) {
Face& f = cur[j];
int res = f.cansee(P, i);
if (!res) nxt.pb(f);
for (int k = 0; k < 3; k ++) vis[f.v[k]][f.v[(k + 1) % 3]]= res;
}
for (int j = 0; j < (int)cur.size(); j ++) {
for (int k = 0; k < 3; k ++) {
int a = cur[j].v[k], b = cur[j].v[(k + 1) % 3];
if (vis[a][b] != vis[b][a] && vis[a][b]) nxt.pb((Face){a, b, i});
}
}
cur = nxt;
}
return cur;
}
int n;
int main() {
srand(19260817);
scanf("%d", &n);
for (int i = 0; i < n; i ++) scanf("%lf%lf%lf", &P[i].x, &P[i].y, &P[i].z);
Ans = CH3D(P, n);
for (int i = 0; i < (int)Ans.size(); i ++) ans += Length(Ans[i].normal(P)) / 2;
printf("%.3lf\n", ans);
return 0;
}