#include #include #include #include #include #define foreach(T,p,c) for(T p = (c).begin(); p != (c).end(); p++) #define EPSILON (1e-12) #define EQ(x,y) (fabs((x)-(y)) < EPSILON) #define LT(x,y) (((x)-(y)) <= -EPSILON) #define INC (1) #define DEC (0) using namespace std; struct sphere_t { double x, y, z, r; public: bool operator ==(const sphere_t &other) const { return x == other.x && y == other.y && z == other.z && r == other.r; } }; istream& operator >>(istream &in, sphere_t &sphere) { in >> sphere.x >> sphere.y >> sphere.z >> sphere.r; return in; } double dist(double x0, double y0, double z0, double x1, double y1, double z1) { return sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0) + (z1-z0)*(z1-z0)); } bool hide(const sphere_t &s, const sphere_t &t, int dir) { double d = dist(s.x, s.y, s.z + s.r * dir, t.x, t.y, t.z); return LT(d, t.r); } double solve(const sphere_t &s, const sphere_t &t, int dir, const vector &spheres) { if(hide(s, t, dir) || hide(t, s, dir)) return HUGE_VAL; double d = dist(s.x, s.y, s.z, t.x, t.y, t.z); if(LT(s.r + t.r, d)) return HUGE_VAL; double z0, z1; z0 = s.z + (t.z - s.z) * s.r / d; z1 = min(s.z * dir + s.r, t.z * dir + t.r) * dir; double z, dz, rs, rt; while(true) { z = (z0 + z1) / 2.0; dz = dist(s.x, s.y, z, t.x, t.y, z); rs = sqrt(s.r * s.r - (s.z - z) * (s.z - z)); rt = sqrt(t.r * t.r - (t.z - z) * (t.z - z)); if(fabs(z1 - z0) < 0.0001) break; if(dz < rs + rt) z0 = z; else z1 = z; } double x = s.x + (t.x - s.x) * rs / dz; double y = s.y + (t.y - s.y) * rs / dz; foreach(vector::const_iterator, p, spheres) { if(*p == s || *p == t) continue; if(LT(dist(x, y, z, p->x, p->y, p->z), p->r)) return HUGE_VAL; } return z; } int main(void) { ifstream cin("H.txt"); int n; while(cin >> n) { if(n == 0) break; vector s(n); for(int i = 0; i < n; i++) cin >> s[i]; vector< pair > v; for(int i = 0; i < n; i++) { bool upper = true; bool lower = true; for(int j = 0; j < n; j++) { if(i == j) continue; if(hide(s[i], s[j], +1)) upper = false; if(hide(s[i], s[j], -1)) lower = false; } if(upper) v.push_back(make_pair(s[i].z + s[i].r, DEC)); if(lower) v.push_back(make_pair(s[i].z - s[i].r, INC)); } for(int i = 0; i < n; i++) { for(int j = i + 1; j < n; j++) { double zu = solve(s[i], s[j], +1, s); if(zu != HUGE_VAL) v.push_back(make_pair(zu, INC)); double zl = solve(s[i], s[j], -1, s); if(zl != HUGE_VAL) v.push_back(make_pair(zl, DEC)); } } sort(v.begin(), v.end()); cout << v.size() << endl; for(int i = 0; i < v.size(); i++) cout << v[i].second; cout << endl; } }