NC15877. Maneuvering
描述
It’s universally acknowledged that there’re innumerable trees in the campus of HUST.
输入描述
The first line contains number n (1≤n≤100), the number of engines.
The second line contains a real number I, indicates the moment of inertia.
For the next n lines, each line contains seven real number F,x,y,z,a,b,c, indicates an engine which has a maximum thrust F(0≤F≤100) towards (a,b,c) is located at (x,y,z), where -100≤x,y,z,a,b,c≤100.
Every real number as input has 6 digits after point.
All data is randomly generated.
输出描述
One line contains the max angular acceleration.
Round your answer to .
示例1
输入:
2 1.000000 3.000000 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 1.000000 -1.000000 0.000000 0.000000 0.000000 -1.000000 0.000000
输出:
2.0000
C++11(clang++ 3.9) 解法, 执行用时: 13ms, 内存消耗: 996K, 提交时间: 2018-05-05 00:30:58
#include <bits/stdc++.h> typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; typedef long double db; typedef unsigned char uchar; using namespace std; #define var auto #define range(i,a,b) for(int i=a, lim_v=(b); i<=lim_v; i++) #define revr(i,a,b) for(int i=a, lim_v=(b); i>=lim_v; i--) #define prln putchar('\n') #define prsp putchar(' ') #define pri(i) printf("%d", (i)) #define prl(i) printf("%lld", (i)) #define cp(dst,src,len) memcpy((&dst), (&src), sizeof(src[0]) * (len)) template<typename T> void read(T& x) { x = 0; bool mi = false; char c = getchar(); while(c != EOF && !isdigit(c) && c != '-') c = getchar(); if(c == '-') { mi = true; c = getchar(); } do { x = x * 10 + c - '0'; } while((c = getchar()) != EOF && isdigit(c)); if(mi) x = -x; } inline int getint() { int x; read(x); return x; } inline ll getll() { ll x; read(x); return x; } db getdb() { static double x; scanf("%lf", &x); return x; } // ======================================================================================= const db eps = 1e-8; bool eq(db a, db b) { return abs(a-b) < eps; } static exception Infeasable; static exception Unbounded; // KuangBin template. typedef vector<db> VD; VD Simplex(vector<VD> A, VD b, VD c) { int n = A.size(), m = A[0].size() + 1, r = n, s = m - 1; vector<VD> D(n + 2, VD(m + 1, 0)); vector<int> ix(n + m); for (int i = 0; i < n + m; ++ i) ix[i] = i; for (int i = 0; i < n; ++ i) { for (int j = 0; j < m - 1; ++ j) D[i][j] = -A[i][j]; D[i][m - 1] = 1; D[i][m] = b[i]; if (D[r][m] > D[i][m]) r = i; } for (int j = 0; j < m - 1; ++ j) D[n][j] = c[j]; D[n + 1][m - 1] = -1; for(db d;;) { if (r < n) { int t = ix[s]; ix[s] = ix[r + m]; ix[r + m] = t; D[r][s] = 1.0 / D[r][s]; vector<int> speedUp; for (int j = 0; j <= m; ++ j) if (j != s) { D[r][j] *= -D[r][s]; if(D[r][j]) speedUp.push_back(j); } for (int i = 0; i <= n + 1; ++ i) if (i != r) { for(int j = 0; j < speedUp.size(); ++ j) D[i][speedUp[j]] += D[r][speedUp[j]] * D[i][s]; D[i][s] *= D[r][s]; }} r = -1; s = -1; for (int j = 0; j < m; ++ j) if (s < 0 || ix[s] > ix[j]) if (D[n + 1][j] > eps || (D[n + 1][j] > -eps && D[n][j] > eps)) s = j; if (s < 0) break; for (int i = 0; i < n; ++ i) if (D[i][s] < -eps) if (r < 0 || (d = D[r][m] / D[r][s] - D[i][m] / D[i][s]) < -eps || (d < eps && ix[r + m] > ix[i + m])) r = i; if (r < 0) throw Infeasable; } if (D[n + 1][m] < -eps) throw Unbounded; VD x(m - 1); for (int i = m; i < n + m; ++ i) if (ix[i] < m - 1) x[ix[i]] = D[i - m][m]; return x; } // ======================================================================================= struct pt{ db x, y, z; }; pt operator*(pt const& a, pt const& b) { return pt { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x }; } pt operator*(pt const& a, db v) { return pt{a.x * v, a.y * v, a.z * v}; } pt operator*(db v, pt const& a) { return pt{a.x * v, a.y * v, a.z * v}; } db len(pt const& v) { return sqrt(v.x * v.x + v.y * v.y + v.z * v.z); } pt norm(pt const& v) { return eq(len(v), 0) ? v : v * (1.0 / len(v)); } db operator&(pt const& a, pt const& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } db T[305]; pt pos[305]; pt thr[305]; pt X{1.0, 0.0, 0.0}; pt Y{0.0, 1.0, 0.0}; pt Z{0.0, 0.0, 1.0}; bool Check(int n, db const& val, VD ans) { db x = 0,y = 0,z = 0,px = 0,py = 0,pz = 0; range(i, 0, n-1) { pt ph = thr[i] * ans[i]; assert(!isnan(ans[i])); x += (pos[i] * ph) & X; y += (pos[i] * ph) & Y; z += (pos[i] * ph) & Z; px += ph & X; py += ph & Y; pz += ph & Z; } auto leq = [](db a, db b) -> bool { return abs(a - b) <= 1e-6; }; assert(leq(z, val)); assert(leq(x, 0)); assert(leq(y, 0)); assert(leq(px, 0)); assert(leq(py, 0)); assert(leq(pz, 0)); return true; } /* x0 x1 x2 ... xn ZR = ANS -------------------------- XR <= eps -XR <= 0 YR <= eps -YR <= 0 XT <= eps -XT <= 0 YT <= eps -YT <= 0 ZT <= eps -ZT <= 0 x0 <= 1 x1 <= 1 x2 <= 1 ... xn <= 1 */ int main() { int n = getint(); db inertia = getdb(); VD c(n); VD b(n + 10); vector<VD> A(n + 10); range(i, 0, n+10-1) A[i].resize(n); b[0] = b[2] = b[4] = b[6] = b[8] = eps; b[1] = b[3] = b[5] = b[7] = b[9] = 0; range(i, 10, n+10-1) b[i] = 1; range(i, 0, n-1) { T[i] = getdb(); pos[i].x = getdb(); pos[i].y = getdb(); pos[i].z = getdb(); thr[i].x = getdb(); thr[i].y = getdb(); thr[i].z = getdb(); thr[i] = T[i] * norm(thr[i]); c[i] = (pos[i] * thr[i]) & Z; A[1][i] = -(A[0][i] = (pos[i] * thr[i]) & X); A[3][i] = -(A[2][i] = (pos[i] * thr[i]) & Y); A[5][i] = -(A[4][i] = thr[i] & X); A[7][i] = -(A[6][i] = thr[i] & Y); A[9][i] = -(A[8][i] = thr[i] & Z); A[10 + i][i] = 1; } int bc = 0; range(i, 0, A.size()-1) { bool ept = true; range(j, 0, n-1) if(!eq(A[i][j], 0)) { ept = false; break; } if(!ept) { range(j, 0, n-1) swap(A[bc][j], A[i][j]); swap(b[bc], b[i]); bc++; } } VD r = Simplex(A, b, c); db L = 0; range(i, 0, n-1) { L += r[i] * c[i]; } printf("%.4f\n", (double) (L < eps ? 0 : L / inertia)); return 0; }