// Necklace #include #include #include #include #include #include using namespace std; /**************************************************************************** * Constants * ****************************************************************************/ #define EPSILON 1.0E-7 /**************************************************************************** * Typedefs * ****************************************************************************/ typedef int varname; typedef double value; struct row { varname base; map coeff; double rhs; row(int N) : base(-1), coeff(), rhs(0.0) {} }; typedef complex point; /**************************************************************************** * Debug Support * ****************************************************************************/ #ifdef _DEBUG ostream& operator << (ostream& out, const vector& tabular) { for(int i = 0; i < tabular.size(); i++) { const row& eqn = tabular[i]; for(map::const_iterator it = eqn.coeff.begin(), eit = eqn.coeff.end(); it != eit; ++it) out << "[" << it->first << "]" << it->second << " "; out << "rhs=" << tabular[i].rhs << endl; } return out; } #endif//_DEBUG /**************************************************************************** * Simplex Method (for solving LP) * ****************************************************************************/ void sweep(vector& tabular, varname c, int r) { // normalize the pivot row row& prow = tabular[r]; { const value saved_coeff = prow.coeff[c]; for(map::iterator it = prow.coeff.begin(), eit = prow.coeff.end(); it != eit; ++it) it->second /= saved_coeff; prow.rhs /= saved_coeff; prow.base = c; } // and sweep out the pivot column from other rows for(int i = 0; i < tabular.size(); i++) { row& eqn = tabular[i]; if(i == r || ! eqn.coeff.count(c)) continue; const value saved_coeff = eqn.coeff[c]; eqn.coeff.erase(c); for(map::iterator it = prow.coeff.begin(), eit = prow.coeff.end(); it != eit; ++it) if(it->first != c) { const varname j = it->first; value v = eqn.coeff.count(j) ? eqn.coeff[j] : 0.0; v -= it->second * saved_coeff; if(fabs(v) < EPSILON) { if(eqn.coeff.count(j)) eqn.coeff.erase(j); } else eqn.coeff[j] = v; } eqn.rhs -= prow.rhs * saved_coeff; } } vector solve(const vector& ps) { // Create tabular const int N = ps.size(); const int rows = N * (N - 1) / 2; const int cols = N + N + rows; vector tabular(rows + 1, row(cols)); int r = 1; varname aval = N, slack = aval + N; // adjacent pairs for(int i = 0; i < ps.size(); i++) { const int j = (i + 1) % ps.size(); tabular[0].coeff[aval] = 1; tabular[0].coeff[i] = -2; row& eqn = tabular[r++]; eqn.coeff[i] = eqn.coeff[j] = 1; eqn.coeff[aval++] = -1; eqn.coeff[eqn.base = slack++] = 1; eqn.rhs = abs(ps[i] - ps[j]); } // non-adjacent pairs for(int i = 0; i < ps.size(); i++) for(int j = i + 2; j < ps.size(); j++) { if(i == 0 && j == ps.size() - 1) continue; row& eqn = tabular[r++]; eqn.coeff[i] = eqn.coeff[j] = 1; eqn.coeff[eqn.base = slack++] = 1; eqn.rhs = abs(ps[i] - ps[j]); } assert(r == 1 + rows); // Simplex method while(1) { #ifdef _DEBUG cerr << tabular; #endif//_DEBUG // Find a pivot varname pcol = -1; value minval = 0; for(map::const_iterator it = tabular[0].coeff.begin(), eit = tabular[0].coeff.end(); it != eit; ++it) if(it->second < minval) pcol = it->first, minval = it->second; if(pcol < 0) break; // Optimal solution is found int prow = -1; for(int r = 1; r <= rows; r++) { if(! tabular[r].coeff.count(pcol) || tabular[r].coeff[pcol] < EPSILON) continue; const value v = tabular[r].rhs / tabular[r].coeff[pcol]; if(prow == -1 || v < minval) prow = r, minval = v; } if(prow < 0) break; sweep(tabular, pcol, prow); #ifdef _DEBUG cerr << "pivot " << pcol << " and " << prow << endl; #endif//_DEBUG } // Create result vector vector result(N, 0.0); for(int i = 1; i < tabular.size(); i++) { if(tabular[i].base >= N) continue; assert(fabs(tabular[i].coeff[tabular[i].base] - 1.0) <= EPSILON); result[tabular[i].base] = tabular[i].rhs; } return result; } /**************************************************************************** * Bootstrap * ****************************************************************************/ int main() { bool first = true; for(int N; cin >> N, N; ) { vector ps; while(N-- > 0) { double x, y; cin >> x >> y; ps.push_back(point(x, y)); } if(first) first = false; else cout << endl; vector rs; rs.clear(); if(ps.size() <= 3) { // obvious cases for(int i = 0; i < ps.size(); i++) { double max_dist = 0.0; for(int j = 0; j < ps.size(); j++) { if(i == j) continue; const double dist = abs(ps[j] - ps[i]) / 2.0; if(dist > max_dist) max_dist = dist; } rs.push_back(max_dist); } } else rs = solve(ps); assert(ps.size() == rs.size()); for(int i = 0; i < rs.size(); i++) { static char buffer[16384]; snprintf(buffer, sizeof buffer, "%.6lf", rs[i]); cout << buffer << endl; } } return 0; }