列表

详情


NC15877. Maneuvering

描述

It’s universally acknowledged that there’re innumerable trees in the campus of HUST.

A space ship commonly uses small engines for its attitude control and maneuvering. DK tells you the engine layout of a ship and the ship’s moment of inertia in local space. Assume the moment of inertia for x, y and z axis are all the same. Tell him the max counter-clockwise angular acceleration on +z axis while the ship has no translation on any axis, and has no rotation on x and y axis. Notice DK uses right-hand coordinate system.

输入描述

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; 
}

上一题