Problem:
Problem F
Secrets in Shadows
Long long ago, there were several identical columns (or cylinders) built vertically in a big open space near Yokohama (Fig. F-1). In the daytime, the shadows of the columns were moving on the ground as the sun moves in the sky. Each column was very tall so that its shadow was very long. The top view of the shadows is shown in Fig. F-2.
The directions of the sun that minimizes and maximizes the widths of the shadows of the columns were said to give the important keys to the secrets of ancient treasures.
Fig. F-1: Columns (or cylinders)
Gig. F-2: Top view of the columns (Fig. F-1) and their shadows
The width of the shadow of each column is the same as the diameter of the base disk. But the width of the whole shadow (the union of the shadows of all the columns) alters according to the direction of the sun since the shadows of some columns may overlap those of other columns.
Fig. F-3 shows the direction of the sun that minimizes the width of the whole shadow for the arrangement of columns in Fig. F-2.
Fig. F-3: The direction of the sun for the minimal width of the whole shadow
Fig. F-4 shows the direction of the sun that maximizes the width of the whole shadow. When the whole shadow is separated into several parts (two parts in this case), the width of the whole shadow is defined as the sum of the widths of the parts.
Fig. F-4: The direction of the sun for the maximal width of the whole shadow
A direction of the sun is specified by an angle
θ
defined in Fig. F-5. For example, the east is indicated by
θ
= 0, the south by
θ
=
π
/2, and the west by
θ
=
π
. You may assume that the sun rises in the east (
θ
= 0) and sets in the west (
θ
=
π
).
Your job is to write a program that, given an arrangement of columns, computes two directions
θ
min
and
θ
max
of the sun that give the minimal width and the maximal width of the whole shadow, respectively.
The position of the center of the base disk of each column is specified by its (
x
,
y
) coordinates. The
x
-axis and
y
-axis are parallel to the line between the east and the west and that between the north and the south, respectively. Their positive directions indicate the east and the north, respectively.
You can assume that the big open space is a plane surface.
Fig. F-5: The definition of the angle of the direction of the sun
There may be more than one
θ
min
or
θ
max
for some arrangements in general, but here, you may assume that we only consider the arrangements that have unique
θ
min
and
θ
max
in the range 0 ≤
θ
min
<
π
, 0 ≤
θ
max
<
π
.
Input
The input consists of multiple datasets, followed by the last line
containing a single zero.
Each dataset is formatted as follows.
n
x
1
y
1
x
2
y
2
...
x
n
y
n
n
is the number of the columns in the big open space. It is a positive integer no more than 100.
x
k
and
y
k
are the values of
x
-coordinate and
y
-coordinate of the center of the base disk of the
k
-th column (
k
=1, ...,
n
). They are positive integers no more than 30. They are s
...(truncated)

Submitted solutions:

code_snippet: #define _CRT_SECURE_NO_WARNINGS 
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cassert>
#include <vector>
typedef long long ll;
typedef long double ld;
//typedef double ld;
typedef std::vector<int> Vint;
typedef std::vector<ld> Vld;
const ld INF = 1e17;
const ld TOL = 1e-20;
const ld PI = acosl(-1);
const int LEN = 10005;
inline int sign(const ld& x) { return x <= -TOL ? -1 : x >= TOL; }
inline bool zero(const ld& x) { return !sign(x); }
inline bool eq(const ld& x, const ld& y) { return zero(x - y); }
inline ll sq(const ll& x) { return x * x; }
inline ld sq(const ld& x) { return x * x; }
inline ld fit(const ld& x, const ld& lo, const ld& hi) { return std::min(hi, std::max(lo, x)); }
inline ld norm(ld th) { while (th < 0) th += 2 * PI; while (sign(th - 2 * PI) >= 0) th -= 2 * PI; return th; }

#define INSIDE 0
#define MEET 1
#define OUTSIDE 2
#define STRONG 0
#define WEAK 1
#define LO x
#define HI y

int N, M;
Vld ANS;
struct Pos {
	ld x, y;
	int i;
	Pos(ld x_ = 0, ld y_ = 0) : x(x_), y(y_) { i = 0; }
	bool operator == (const Pos& p) const { return zero(x - p.x) && zero(y - p.y); }
	bool operator != (const Pos& p) const { return !zero(x - p.x) || !zero(y - p.y); }
	bool operator < (const Pos& p) const { return zero(x - p.x) ? y < p.y : x < p.x; }
	bool operator <= (const Pos& p) const { return *this < p || *this == p; }
	Pos operator + (const Pos& p) const { return { x + p.x, y + p.y }; }
	Pos operator - (const Pos& p) const { return { x - p.x, y - p.y }; }
	Pos operator * (const ld& n) const { return { x * n, y * n }; }
	Pos operator / (const ld& n) const { return { x / n, y / n }; }
	ld operator * (const Pos& p) const { return x * p.x + y * p.y; }
	ld operator / (const Pos& p) const { return x * p.y - y * p.x; }
	Pos operator ^ (const Pos& p) const { return { x * p.x, y * p.y }; }
	Pos& operator += (const Pos& p) { x += p.x; y += p.y; return *this; }
	Pos& operator -= (const Pos& p) { x -= p.x; y -= p.y; return *this; }
	Pos& operator *= (const ld& n) { x *= n; y *= n; return *this; }
	Pos& operator /= (const ld& n) { x /= n; y /= n; return *this; }
	Pos operator - () const { return { -x, -y }; }
	Pos operator ~ () const { return { -y, x }; }
	Pos operator ! () const { return { y, x }; }
	ld xy() const { return x * y; }
	Pos rot(const ld& the) const { return { x * cosl(the) - y * sinl(the), x * sinl(the) + y * cosl(the) }; }
	ld Euc() const { return x * x + y * y; }
	ld mag() const { return sqrtl(Euc()); }
	Pos unit() const { return *this / mag(); }
	ld rad() const { return atan2l(y, x); }
	friend ld rad(const Pos& p1, const Pos& p2) { return atan2l(p1 / p2, p1 * p2); }
	int quad() const { return sign(y) == 1 || (sign(y) == 0 && sign(x) >= 0); }
	friend bool cmpq(const Pos& a, const Pos& b) { return (a.quad() != b.quad()) ? a.quad() < b.quad() : a / b > 0; }
	bool close(const Pos& p) const { return zero((*this - p).Euc()); }
	friend std::istream& operator >> (std::istream& is, Pos& p) { is >> p.x >> p.y; return is; }
	friend std::ostream& operator << (std::ostream& os, const Pos& p) { os << p.x << " " << p.y; return os; }
}; const Pos O = Pos(0, 0);
typedef std::vector<Pos> Polygon;
ld cross(const Pos& d1, const Pos& d2, const Pos& d3) { return (d2 - d1) / (d3 - d2); }
ld cross(const Pos& d1, const Pos& d2, const Pos& d3, const Pos& d4) { return (d2 - d1) / (d4 - d3); }
int ccw(const Pos& d1, const Pos& d2, const Pos& d3) { return sign(cross(d1, d2, d3)); }
ld dot(const Pos& d1, const Pos& d2, const Pos& d3) { return (d2 - d1) * (d3 - d2); }
ld dot(const Pos& d1, const Pos& d2, const Pos& d3, const Pos& d4) { return (d2 - d1) * (d4 - d3); }
Pos intersection(const Pos& p1, const Pos& p2, const Pos& q1, const Pos& q2) { ld a1 = cross(q1, q2, p1), a2 = -cross(q1, q2, p2); return (p1 * a2 + p2 * a1) / (a1 + a2); }
bool inner_check(const Polygon& H, const Pos& p) {
	int sz = H.size();
	for (int i = 0; i < sz; i++) if (ccw(H[i], H[(i + 1) % sz], p) < 0) return 0;
	return 1;
}
struct Seg {
	Pos s, e;
	Seg(Pos s_ = Pos(), Pos e_ = Pos()) : s(s_), e(e_) {}
	Pos p(const ld& rt) const { return s + (e - s) * rt; }
	ld green(const ld& lo = 0, const ld& hi = 1) const {
		ld d = hi - lo;
		ld ratio = (lo + hi) * .5;
		Pos m = p(ratio);
		return m.y * d * (s.x - e.x);
	}
};
ld intersection(const Seg& s1, const Seg& s2, const bool& f = STRONG) {
	const Pos& p1 = s1.s, p2 = s1.e, q1 = s2.s, q2 = s2.e;
	ld det = (q2 - q1) / (p2 - p1);
	if (zero(det)) return -1;
	ld a1 = ((q2 - q1) / (q1 - p1)) / det;
	ld a2 = ((p2 - p1) / (p1 - q1)) / -det;
	if (f == WEAK) return a1;
	if (0 < a1 && a1 < 1 && -TOL < a2 && a2 < 1 + TOL) return a1;
	return -1;
}
Pos get_vec(const Polygon& P, const Polygon& V) {
	Pos ab = Pos(0, 0);//a * sin(t) + b * cos(t) + c = 0
	int sz = V.size();
	for (int i = 0; i < sz; i++) {
		if (i < sz - 1 && V[i].HI > V[i + 1].LO) {
			Pos v = P[V[i + 1].i] - P[V[i].i];
			ab += v;
		}
	}
	return ab;
}
bool query() {
	ld min = INF, max = -1;
	ld mint = 0, maxt = 0;
	std::cin >> N;
	if (!N) return 0;
	Polygon P(N); for (Pos& p : P) std::cin >> p, p.y *= -1;
	Polygon V;
	Vld T = { 0, PI };
	for (int i = 0; i < N; i++) {
		for (int j = i + 1; j < N; j++) {
			Pos v = (P[j] - P[i]);
			ld l = v.mag();
			//v = v.unit();
			if (v < O) v *= -1;
			T.push_back(norm(v.rad()));
			ld t = asinl(2 / l);
			Pos v1 = v.rot(t);
			if (v1 < O) v1 *= -1;
			T.push_back(norm(v1.rad()));
			Pos v2 = v.rot(-t);
			if (v2 < O) v2 *= -1;
			T.push_back(norm(v2.rad()));
		}
	}
	std::sort(T.begin(), T.end());
	T.erase(unique(T.begin(), T.end()), T.end());
	int sz = T.size();
	for (int i = 0; i < sz - 1; i++) {
		ld s = T[i], e = T[i + 1];
		ld m = (s + e) * .5;
		Pos v = Pos(1, 0).rot(m);
		Pos h = ~v;
		Seg I = Seg(O, h);
		Polygon V;
		ld x;
		for (int k = 0; k < N; k++) {
			Pos p = P[k];
			Pos q = p + v;
			Seg K = Seg(p, q);
			x = intersection(I, K, WEAK);
			Pos r = Pos(x - 1, x + 1);
			r.i = k;
			V.push_back(r);
		}
		std::sort(V.begin(), V.end());
		Pos ab = get_vec(P, V);
		T.push_back(norm(ab.rad()));
		T.push_back(norm((~ab).rad()));
	}
	std::sort(T.begin(), T.end());
	T.erase(unique(T.begin(), T.end()), T.end());
	for (const ld& t : T) {
		Pos v = Pos(1, 0).rot(t);
		Pos h = ~v;
		Seg I = Seg(O, h);
		Polygon V;
		ld x;
		for (const Pos& p : P) {
			Pos q = p + v;
			Seg K = Seg(p, q);
			x = intersection(I, K, WEAK);
			Pos r = Pos(x - 1, x + 1);
			V.push_back(r);
		}
		std::sort(V.begin(), V.end());
		V.erase(unique(V.begin(), V.end()), V.end());
		x = 0;
		int sz = V.size();
		for (int i = 0; i < sz; i++) {
			if (i < sz - 1 && V[i].HI > V[i + 1].LO) x += (V[i + 1].LO - V[i].LO);
			else x += V[i].HI - V[i].LO;
		}
		if (min > x) { min = x; mint = std::min(norm(v.rad()), norm(v.rad() + PI)); }
		if (max < x) { max = x; maxt = std::min(norm(v.rad()), norm(v.rad() + PI)); }
	}
	std::cout << mint << "\n" << maxt << "\n";
	//ANS.push_back(mint);
	//ANS.push_back(maxt);
	return 1;
}
void solve() {
	std::cin.tie(0)->sync_with_stdio(0);
	std::cout.tie(0);
	std::cout << std::fixed;
	std::cout.precision(11);
	while (query());
	//for (const ld& ans : ANS) std::cout << ans << "\n";
	//for (const ld& ans : ANS) {
	//	ld x;
	//	std::cin >> x;
	//	std::cout << ans << "\n";
	//	ld err = (ans - x) / ans;
	//	if (zero(x)) std::cout << "answer is zero and my result is " << ans << "\n";
	//	else std::cout << err << "\n";
	//	if (std::abs(err) > 1e-10) std::cout << "FUCK::\n";
	//	else std::cout << "GOOD\n";
	//}
	return;
}
int main() { solve(); return 0; }//boj4985 Secrets in Shadows



//struct Circle {
//	Pos c;
//	ll r;
//	Circle(Pos c_ = Pos(), ll r_ = 0) : c(c_), r(r_) {}
//	bool operator > (const Pos& p) const { return sign(r - (c - p).mag()) > 0; }
//	Pos p(const ld& t) const { return c + Pos(r, 0).rot(t); }
//	ld rad(const Pos& p) const { return (p - c).rad(); }
//	ld area(const ld& lo, const ld& hi) const { return (hi - lo) * r * r * .5; }
//	ld green(const ld& lo, const ld& hi) const {
//		Pos s = Pos(cos(lo), sin(lo)), e = Pos(cos(hi), sin(hi));
//		ld fan = area(lo, hi);
//		Pos m = c + (s + e) * r * (ld).5;
//		ld tz = (cos(lo) - cos(hi)) * m.y * r;
//		return fan + tz - (s / e) * r * r * (ld).5;
//	}
//	friend std::istream& operator >> (std::istream& is, Circle& p) { is >> p.c.x >> p.c.y >> p.r; return is; }
//	friend std::ostream& operator << (std::ostream& os, const Circle& p) { os << p.c.x << " " << p.c.y << " " << p.r; return os; }
//} C[3];
//Vld intersections(const Circle& a, const Circle& b) {
//	Pos ca = a.c, cb = b.c;
//	Pos vec = cb - ca;
//	ld ra = a.r, rb = b.r;
//	ld distance = vec.mag();
//	ld rd = vec.rad();
//	if (vec.Euc() > sq(ra + rb) + TOL) return {};
//	if (vec.Euc() < sq(ra - rb) - TOL) return {};
//	ld X = (ra * ra - rb * rb + vec.Euc()) / (2 * distance * ra);
//	if (X < -1) X = -1;
//	if (X > 1) X = 1;
//	ld h = acos(X);
//	Vld ret = {};
//	ret.push_back(norm(rd - h));
//	if (zero(h)) return ret;
//	ret.push_back(norm(rd + h));
//	return ret;
//}
accuracy: 1
time_ms: 530
memory_kb: 4268
final_rank: 13

code_snippet: #define _CRT_SECURE_NO_WARNINGS 
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cassert>
#include <vector>
typedef long long ll;
typedef long double ld;
//typedef double ld;
typedef std::vector<int> Vint;
typedef std::vector<ld> Vld;
const ld INF = 1e17;
const ld TOL = 1e-20;
const ld PI = acosl(-1);
const int LEN = 10005;
inline int sign(const ld& x) { return x <= -TOL ? -1 : x >= TOL; }
inline bool zero(const ld& x) { return !sign(x); }
inline bool eq(const ld& x, const ld& y) { return zero(x - y); }
inline ll sq(const ll& x) { return x * x; }
inline ld sq(const ld& x) { return x * x; }
inline ld fit(const ld& x, const ld& lo, const ld& hi) { return std::min(hi, std::max(lo, x)); }
inline ld norm(ld th) { while (th < 0) th += 2 * PI; while (sign(th - 2 * PI) >= 0) th -= 2 * PI; return th; }

#define INSIDE 0
#define MEET 1
#define OUTSIDE 2
#define STRONG 0
#define WEAK 1
#define LO x
#define HI y

int N, M;
Vld ANS;
struct Pos {
	ld x, y;
	int i;
	Pos(ld x_ = 0, ld y_ = 0) : x(x_), y(y_) { i = 0; }
	bool operator == (const Pos& p) const { return zero(x - p.x) && zero(y - p.y); }
	bool operator != (const Pos& p) const { return !zero(x - p.x) || !zero(y - p.y); }
	bool operator < (const Pos& p) const { return zero(x - p.x) ? y < p.y : x < p.x; }
	bool operator <= (const Pos& p) const { return *this < p || *this == p; }
	Pos operator + (const Pos& p) const { return { x + p.x, y + p.y }; }
	Pos operator - (const Pos& p) const { return { x - p.x, y - p.y }; }
	Pos operator * (const ld& n) const { return { x * n, y * n }; }
	Pos operator / (const ld& n) const { return { x / n, y / n }; }
	ld operator * (const Pos& p) const { return x * p.x + y * p.y; }
	ld operator / (const Pos& p) const { return x * p.y - y * p.x; }
	Pos operator ^ (const Pos& p) const { return { x * p.x, y * p.y }; }
	Pos& operator += (const Pos& p) { x += p.x; y += p.y; return *this; }
	Pos& operator -= (const Pos& p) { x -= p.x; y -= p.y; return *this; }
	Pos& operator *= (const ld& n) { x *= n; y *= n; return *this; }
	Pos& operator /= (const ld& n) { x /= n; y /= n; return *this; }
	Pos operator - () const { return { -x, -y }; }
	Pos operator ~ () const { return { -y, x }; }
	Pos operator ! () const { return { y, x }; }
	ld xy() const { return x * y; }
	Pos rot(ld the) const { return { x * cosl(the) - y * sinl(the), x * sinl(the) + y * cosl(the) }; }
	ld Euc() const { return x * x + y * y; }
	ld mag() const { return sqrtl(Euc()); }
	Pos unit() const { return *this / mag(); }
	ld rad() const { return atan2l(y, x); }
	friend ld rad(const Pos& p1, const Pos& p2) { return atan2l(p1 / p2, p1 * p2); }
	int quad() const { return sign(y) == 1 || (sign(y) == 0 && sign(x) >= 0); }
	friend bool cmpq(const Pos& a, const Pos& b) { return (a.quad() != b.quad()) ? a.quad() < b.quad() : a / b > 0; }
	bool close(const Pos& p) const { return zero((*this - p).Euc()); }
	friend std::istream& operator >> (std::istream& is, Pos& p) { is >> p.x >> p.y; return is; }
	friend std::ostream& operator << (std::ostream& os, const Pos& p) { os << p.x << " " << p.y; return os; }
}; const Pos O = Pos(0, 0);
typedef std::vector<Pos> Polygon;
ld cross(const Pos& d1, const Pos& d2, const Pos& d3) { return (d2 - d1) / (d3 - d2); }
ld cross(const Pos& d1, const Pos& d2, const Pos& d3, const Pos& d4) { return (d2 - d1) / (d4 - d3); }
int ccw(const Pos& d1, const Pos& d2, const Pos& d3) { return sign(cross(d1, d2, d3)); }
ld dot(const Pos& d1, const Pos& d2, const Pos& d3) { return (d2 - d1) * (d3 - d2); }
ld dot(const Pos& d1, const Pos& d2, const Pos& d3, const Pos& d4) { return (d2 - d1) * (d4 - d3); }
Pos intersection(const Pos& p1, const Pos& p2, const Pos& q1, const Pos& q2) { ld a1 = cross(q1, q2, p1), a2 = -cross(q1, q2, p2); return (p1 * a2 + p2 * a1) / (a1 + a2); }
bool inner_check(const Polygon& H, const Pos& p) {
	int sz = H.size();
	for (int i = 0; i < sz; i++) if (ccw(H[i], H[(i + 1) % sz], p) < 0) return 0;
	return 1;
}
struct Seg {
	Pos s, e;
	Seg(Pos s_ = Pos(), Pos e_ = Pos()) : s(s_), e(e_) {}
	Pos p(const ld& rt) const { return s + (e - s) * rt; }
	ld green(const ld& lo = 0, const ld& hi = 1) const {
		ld d = hi - lo;
		ld ratio = (lo + hi) * .5;
		Pos m = p(ratio);
		return m.y * d * (s.x - e.x);
	}
};
ld intersection(const Seg& s1, const Seg& s2, const bool& f = STRONG) {
	const Pos& p1 = s1.s, p2 = s1.e, q1 = s2.s, q2 = s2.e;
	ld det = (q2 - q1) / (p2 - p1);
	if (zero(det)) return -1;
	ld a1 = ((q2 - q1) / (q1 - p1)) / det;
	ld a2 = ((p2 - p1) / (p1 - q1)) / -det;
	if (f == WEAK) return a1;
	if (0 < a1 && a1 < 1 && -TOL < a2 && a2 < 1 + TOL) return a1;
	return -1;
}
Pos get_vec(const Polygon& P, const Polygon& V) {
	Pos ab = Pos(0, 0);//a * sin(t) + b * cos(t) + c = 0
	int sz = V.size();
	for (int i = 0; i < sz; i++) {
		if (i < sz - 1 && V[i].HI > V[i + 1].LO) {
			Pos v = P[V[i + 1].i] - P[V[i].i];
			ab += v;
		}
	}
	return ab;
}
bool query() {
	ld min = INF, max = -1;
	ld mint = 0, maxt = 0;
	std::cin >> N;
	if (!N) return 0;
	Polygon P(N); for (Pos& p : P) std::cin >> p, p.y *= -1;
	Polygon V;
	Vld T = { 0, PI };
	for (int i = 0; i < N; i++) {
		for (int j = i + 1; j < N; j++) {
			Pos v = (P[j] - P[i]);
			ld l = v.mag();
			//v = v.unit();
			if (v < O) v *= -1;
			T.push_back(norm(v.rad()));
			ld t = asinl(2 / l);
			Pos v1 = v.rot(t);
			if (v1 < O) v1 *= -1;
			T.push_back(norm(v1.rad()));
			Pos v2 = v.rot(-t);
			if (v2 < O) v2 *= -1;
			T.push_back(norm(v2.rad()));
		}
	}
	std::sort(T.begin(), T.end());
	T.erase(unique(T.begin(), T.end()), T.end());
	int sz = T.size();
	for (int i = 0; i < sz - 1; i++) {
		ld s = T[i], e = T[i + 1];
		ld m = (s + e) * .5;
		Pos v = Pos(1, 0).rot(m);
		Pos h = ~v;
		Seg I = Seg(O, h);
		Polygon V;
		ld x;
		for (int k = 0; k < N; k++) {
			Pos p = P[k];
			Pos q = p + v;
			Seg K = Seg(p, q);
			x = intersection(I, K, WEAK);
			Pos r = Pos(x - 1, x + 1);
			r.i = k;
			V.push_back(r);
		}
		std::sort(V.begin(), V.end());
		Pos ab = get_vec(P, V);
		T.push_back(norm(ab.rad()));
		T.push_back(norm((~ab).rad()));
	}
	std::sort(T.begin(), T.end());
	T.erase(unique(T.begin(), T.end()), T.end());
	for (const ld& t : T) {
		Pos v = Pos(1, 0).rot(t);
		Pos h = ~v;
		Seg I = Seg(O, h);
		Polygon V;
		ld x;
		for (const Pos& p : P) {
			Pos q = p + v;
			Seg K = Seg(p, q);
			x = intersection(I, K, WEAK);
			Pos r = Pos(x - 1, x + 1);
			V.push_back(r);
		}
		std::sort(V.begin(), V.end());
		V.erase(unique(V.begin(), V.end()), V.end());
		x = 0;
		int sz = V.size();
		for (int i = 0; i < sz; i++) {
			if (i < sz - 1 && V[i].HI > V[i + 1].LO) x += (V[i + 1].LO - V[i].LO);
			else x += V[i].HI - V[i].LO;
		}
		if (min > x) { min = x; mint = std::min(norm(v.rad()), norm(v.rad() + PI)); }
		if (max < x) { max = x; maxt = std::min(norm(v.rad()), norm(v.rad() + PI)); }
	}
	//std::cout << mint << "\n" << maxt << "\n";
	ANS.push_back(mint);
	ANS.push_back(maxt);
	return 1;
}
void solve() {
	std::cin.tie(0)->sync_with_stdio(0);
	std::cout.tie(0);
	std::cout << std::fixed;
	std::cout.precision(11);
	while (query());
	for (const ld& ans : ANS) std::cout << ans << "\n";
	//for (const ld& ans : ANS) {
	//	ld x;
	//	std::cin >> x;
	//	std::cout << ans << "\n";
	//	ld err = (ans - x) / ans;
	//	if (zero(x)) std::cout << "answer is zero and my result is " << ans << "\n";
	//	else std::cout << err << "\n";
	//	if (std::abs(err) > 1e-10) std::cout << "FUCK::\n";
	//	else std::cout << "GOOD\n";
	//}
	return;
}
int main() { solve(); return 0; }//boj4985 Secrets in Shadows



//struct Circle {
//	Pos c;
//	ll r;
//	Circle(Pos c_ = Pos(), ll r_ = 0) : c(c_), r(r_) {}
//	bool operator > (const Pos& p) const { return sign(r - (c - p).mag()) > 0; }
//	Pos p(const ld& t) const { return c + Pos(r, 0).rot(t); }
//	ld rad(const Pos& p) const { return (p - c).rad(); }
//	ld area(const ld& lo, const ld& hi) const { return (hi - lo) * r * r * .5; }
//	ld green(const ld& lo, const ld& hi) const {
//		Pos s = Pos(cos(lo), sin(lo)), e = Pos(cos(hi), sin(hi));
//		ld fan = area(lo, hi);
//		Pos m = c + (s + e) * r * (ld).5;
//		ld tz = (cos(lo) - cos(hi)) * m.y * r;
//		return fan + tz - (s / e) * r * r * (ld).5;
//	}
//	friend std::istream& operator >> (std::istream& is, Circle& p) { is >> p.c.x >> p.c.y >> p.r; return is; }
//	friend std::ostream& operator << (std::ostream& os, const Circle& p) { os << p.c.x << " " << p.c.y << " " << p.r; return os; }
//} C[3];
//Vld intersections(const Circle& a, const Circle& b) {
//	Pos ca = a.c, cb = b.c;
//	Pos vec = cb - ca;
//	ld ra = a.r, rb = b.r;
//	ld distance = vec.mag();
//	ld rd = vec.rad();
//	if (vec.Euc() > sq(ra + rb) + TOL) return {};
//	if (vec.Euc() < sq(ra - rb) - TOL) return {};
//	ld X = (ra * ra - rb * rb + vec.Euc()) / (2 * distance * ra);
//	if (X < -1) X = -1;
//	if (X > 1) X = 1;
//	ld h = acos(X);
//	Vld ret = {};
//	ret.push_back(norm(rd - h));
//	if (zero(h)) return ret;
//	ret.push_back(norm(rd + h));
//	return ret;
//}
accuracy: 1
time_ms: 540
memory_kb: 3948
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pi;
typedef vector<ll> vi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
int main(){
    vector<ld>A(100);
    while(1){
        ll N;cin>>N;
        if(!N)return 0;
        vi X(N),Y(N);
        REP(i,N)cin>>X[i]>>Y[i];
        vector<ld>koho;
        REP(i,N)REP(j,N)if(i!=j){
            ll x=X[i]-X[j];
            ll y=Y[i]-Y[j];
            ll d=x*x+y*y;
            assert(d>=4);
            ld a=sqrtl(d-4);
            if(2*x+y*a>0||(2*x+y*a==0&&2*y-x*a>0))koho.emplace_back(atan2l(2*x+y*a,2*y-x*a));
            if(2*x-y*a>0||(2*x-y*a==0&&2*y+x*a>0))koho.emplace_back(atan2l(2*x-y*a,2*y+x*a));
        }
        REP(i,N)REP(j,i){
            ll x=X[i]-X[j];
            ll y=Y[j]-Y[i];
            if(y<0||(y==0&&x<0))x*=-1,y*=-1;
            koho.emplace_back(atan2l(y,x));
        }
        koho.emplace_back(0);
        koho.emplace_back(acos(-1)-(1e-13));
        sort(ALL(koho));
        koho.erase(unique(ALL(koho)),koho.end());
        auto val=[&](ld theta){
            ld s=sinl(theta);
            ld c=cosl(theta);
            REP(i,N)A[i]=X[i]*s+Y[i]*c;
            sort(A.begin(),A.begin()+N);
            ld ans=2;
            REP(i,N-1)ans+=min((ld)2,A[i+1]-A[i]);
            return ans;
        };
        auto _koho=koho;
        REP(i,koho.size()-1){
            ld theta3=(koho[i]+koho[i+1])*0.5;
            vector<ll>idx(N);
            iota(ALL(idx),0);
            sort(ALL(idx),[&](ll i,ll j){return X[i]*sinl(theta3)+Y[i]*cosl(theta3)<X[j]*sinl(theta3)+Y[j]*cosl(theta3);});
            vector<ld>P(N);
            REP(i,N)P[i]=X[idx[i]]*sinl(theta3)+Y[idx[i]]*cosl(theta3);
            ll a=0,b=0;
            REP(i,N-1)if(P[i+1]-P[i]<2)a+=X[idx[i+1]]-X[idx[i]],b+=Y[idx[i+1]]-Y[idx[i]];
            if(a<0||(a==0&&b<0))a=-a,b=-b;
            if(a!=0||b!=0)_koho.emplace_back(atan2l(a,b));
        }
        koho=_koho;
        ld theta_min=0,theta_max=0;
        ld val_min=1e18,val_max=-1e18;
        for(auto theta:koho){
            if(theta<0)theta+=acosl(-1);
            ld v=val(theta);
            if(v<val_min)theta_min=theta,val_min=v;
            if(v>val_max)theta_max=theta,val_max=v;
        }
        printf("%.20Lf\n%.20Lf\n",theta_min,theta_max);
    }
    return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 4240
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
const long double INF = 1000;
const long double PI = acos(-1);
struct point{
  long double x, y;
  point(){
  }
  point(long double x, long double y): x(x), y(y){
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
};
long double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
long double dist(point P, point Q){
  return abs(Q - P);
}
long double angle(point P){
  long double ans = atan2(P.y, P.x);
  if (ans < 0){
    ans += PI;
  }
  return ans;
}
pair<long double, long double> get_min(long double s, long double c, long double a, long double L, long double R){
  long double A = hypot(s, c);
  long double t = atan2(c, s);
  pair<long double, long double> ans = make_pair(INF, 0);
  long double t1 = -PI / 2 - t;
  if (L <= t1 && t1 <= R){
    ans = min(ans, make_pair(A + a, t1));
  }
  long double t2 = 3 * PI / 2 - t;
  if (L <= t2 && t2 <= R){
    ans = min(ans, make_pair(A + a, t2));
  }
  ans = min(ans, make_pair(A * sin(L + t) + a, L));
  ans = min(ans, make_pair(A * sin(R + t) + a, R));
  return ans;
}
pair<long double, long double> get_max(long double s, long double c, long double a, long double L, long double R){
  long double A = hypot(s, c);
  long double t = atan2(c, s);
  pair<long double, long double> ans = make_pair(0, 0);
  long double t1 = PI / 2 - t;
  if (L <= t1 && t1 <= R){
    ans = max(ans, make_pair(A + a, t1));
  }
  ans = max(ans, make_pair(A * sin(L + t) + a, L));
  ans = max(ans, make_pair(A * sin(R + t) + a, R));
  return ans;
}
int main(){
  cout << fixed << setprecision(20);
  while (true){
    int n;
    cin >> n;
    if (n == 0){
      break;
    }
    vector<point> P(n);
    for (int i = 0; i < n; i++){
      cin >> P[i].x >> P[i].y;
    }
    vector<long double> T;
    T.push_back(0);
    T.push_back(PI);
    for (int i = 0; i < n; i++){
      for (int j = i + 1; j < n; j++){
        long double t = PI - angle(P[j] - P[i]);
        T.push_back(t);
        long double d = dist(P[i], P[j]);
        if (d > 2.1){
          long double p = asin(2 / d);
          T.push_back(fmod(t + p, PI));
          T.push_back(fmod(t - p + PI, PI));
        }
      }
    }
    sort(T.begin(), T.end());
    int cnt = T.size();
    pair<long double, long double> mn = make_pair(INF, 0);
    pair<long double, long double> mx = make_pair(0, 0);
    for (int i = 0; i < cnt - 1; i++){
      long double t = (T[i] + T[i + 1]) / 2;
      vector<pair<long double, int>> R;
      for (int j = 0; j < n; j++){
        R.push_back(make_pair(P[j].x * sin(t) + P[j].y * cos(t) - 1, ~j));
        R.push_back(make_pair(P[j].x * sin(t) + P[j].y * cos(t) + 1, j));
      }
      sort(R.begin(), R.end());
      long double s = 0, c = 0, a = 0;
      int cnt = 0;
      for (int j = 0; j < n * 2; j++){
        int id = R[j].second;
        int add = -1;
        if (id < 0){
          add = 1;
          id = ~id;
        }
        if (cnt == 0){
          s -= P[id].x;
          c -= P[id].y;
          a++;
        }
        cnt += add;
        if (cnt == 0){
          s += P[id].x;
          c += P[id].y;
          a++;
        }
      }
      mn = min(mn, get_min(s, c, a, T[i], T[i + 1]));
      mx = max(mx, get_max(s, c, a, T[i], T[i + 1]));
    }
    cout << mn.second << endl;
    cout << mx.second << endl;
  }
}
accuracy: 1
time_ms: 1220
memory_kb: 4288
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define pt(x) cout << x << endl;
#define Mid ((l + r) / 2)
#define lson (rt << 1)
#define rson (rt << 1 | 1)
using namespace std;
const double Pi = acos(-1.0);
const double eps = 1e-11;
struct Point {
	double x, y;
	Point() : x(0), y(0) {}
	Point(double x, double y) : x(x), y(y) {}
	Point operator+(const Point &a)const{ return Point(x + a.x, y + a.y); }
	Point operator-(const Point &a)const{ return Point(x - a.x, y - a.y); }
} a[109];
typedef Point Vector;
struct line{
	Point a, b;
	line() {}
	line(const Point &a,const Point &b) : a(a), b(b) {}
};
 
struct circle{
	Point c;
	double r;
	circle() : c(Point(0,0)), r(0) {}
	circle(const Point &c, double r) : c(c), r(r) {}
};
Point operator*(double c, const Point &a){ return Point(c * a.x, c * a.y); }
double abs(const Point &a){ return sqrt(a.x * a.x + a.y * a.y); }
Point rot(const Point &a, double theta){ return Point(a.x * cos(theta) - a.y * sin(theta), a.x * sin(theta) + a.y * cos(theta)); }
double arg(const Point &a){
	double t = atan2(a.y, a.x);
	return t < 0 ? t + 2 * Pi:t;
}
int tangent(const circle &C1,const circle &C2,vector<line> &res){
	double d = abs(C1.c - C2.c);
	if(d < eps) return 0;
 
	int c=0;
	if(C1.r + C2.r < d - eps){
		double t = acos((C1.r + C2.r) / d);
		res.push_back(line(C1.c + rot(C1.r / d * (C2.c - C1.c), t), C2.c + rot(C2.r / d * (C1.c - C2.c), t)));
		res.push_back(line(C1.c + rot(C1.r / d * (C2.c - C1.c),-t), C2.c + rot(C2.r / d * (C1.c - C2.c),-t)));
		c += 2;
	} else if(C1.r + C2.r < d + eps){
		Point p = C1.c + C1.r / d * (C2.c - C1.c);
		res.push_back(line(p, p + rot(C2.c - C1.c, Pi / 2)));
		c++;
	}
 
	if(abs(C1.r - C2.r) < d - eps){
		double t1 = acos((C1.r - C2.r) / d), t2 = Pi - t1;
		res.push_back(line(C1.c + rot(C1.r / d * (C2.c - C1.c), t1), C2.c + rot(C2.r / d * (C1.c - C2.c),-t2)));
		res.push_back(line(C1.c + rot(C1.r / d * (C2.c - C1.c),-t1), C2.c + rot(C2.r / d * (C1.c - C2.c), t2)));
		c+=2;
	} else if(abs(C1.r - C2.r) < d + eps){
		Point p = C1.c + C1.r / d * (C2.c - C1.c);
		res.push_back(line(p, p + rot(C2.c - C1.c, Pi / 2)));
		c++;
	}
 
	return c;
}
 
int n;
double maxn, minn, sima, simi;
double calc(double theta) {
	double tt[109] = {0};
	for(int k = 1; k <= n; k++) {
		tt[k] = rot(a[k], theta).y;
	}
	sort(tt + 1, tt + 1 + n);
	double mr = 0, sum = 0;
	sum = 2.0;
	mr = tt[1] + 1.0;
	for(int k = 1; k <= n; k++) {
		if(tt[k] + 1.0 < mr) continue;
		if(tt[k] - 1.0 < mr) {
			sum += tt[k] + 1.0 - mr;
		} else {
			sum += 2.0;
		}
		mr = tt[k] + 1.0;
	}
	return sum;
}
double calc_peak(double phi) {
	pair<double, int> p[109];
	for(int i = 1; i <= n; i++) {
		p[i] = make_pair(rot(a[i], phi).y, i);
	}
	sort(p + 1, p + 1 + n);
	int pre = 1;
	double x = 0, y = 0;
	for(int i = 2; i <= n + 1; i++) {
		if(i == n + 1 || p[i - 1].first + 1 < p[i].first - 1) {
			x += (a[p[i - 1].second].x - a[p[pre].second].x);
			y += (a[p[i - 1].second].y - a[p[pre].second].y);
			pre = i;
		}
	}
	double ans = arg({y, x});
	if(ans > Pi) ans -= Pi;
	return ans;
}
 
void work() {
	if(n == 0) exit(0);
	for(int i = 1; i <= n; i++) 
		scanf("%lf%lf", &a[i].x, &a[i].y);
	maxn = -1e18;
	minn = 1e18;
	vector<line> v;
	for(int i = 1; i <= n; i++) {
		for(int j = i + 1; j <= n; j++) {
			tangent(circle(a[i], 1.0), circle(a[j], 1.0), v);
		}
	}
	vector<double> th;
	for(int i = 0; i < v.size(); i++) {
		line &l = v[i];
		double tt = arg(l.b - l.a);
		if(tt < Pi) tt = Pi - tt;
		else tt = 2 * Pi - tt;
		th.push_back(tt);
	}
	th.push_back(0);
	th.push_back(Pi);
	sort(th.begin(), th.end());
	int tot = 0;
	for(int i = 0; i < th.size(); i++) 
		if(i == 0 || th[i] > th[i - 1] + eps) 
			th[tot++] = th[i];
	th.erase(th.begin() + tot, th.end());
	for(int i = 0; i < tot; i++) {
		double sum = calc(th[i]);
		if(sum > maxn + eps) {
			maxn = sum;
			sima = th[i];
		}
		if(sum < minn - eps) {
			minn = sum;
			simi = th[i];
		}
		if(i - 1 >= 0) {
			double phi0 = (th[i - 1] + th[i]) / 2;
			double phi1 = calc_peak(phi0);
			double sum = calc(phi1);
			if(sum > maxn + eps) {
				maxn = sum;
				sima = phi1;
			}
			if(sum < minn - eps) {
				minn = sum;
				simi = phi1;
			}
		}
	}
	printf("%.15f\n%.15f\n", simi, sima);
}
signed main()
{
	ios :: sync_with_stdio(0);
	cin.tie(0);
	while(~scanf("%d", &n)) work(); 
	return 0;
}
/*
枚举两个圆柱体相切的位置
 
*/
accuracy: 1
time_ms: 780
memory_kb: 5016
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#define pt(x) cout << x << endl;
#define Mid ((l + r) / 2)
#define lson (rt << 1)
#define rson (rt << 1 | 1)
using namespace std;
const double Pi = acos(-1.0);
const double eps = 1e-11;
struct Point {
	double x, y;
	Point() : x(0), y(0) {}
	Point(double x, double y) : x(x), y(y) {}
	Point operator+(const Point &a)const{ return Point(x + a.x, y + a.y); }
	Point operator-(const Point &a)const{ return Point(x - a.x, y - a.y); }
} a[109];
typedef Point Vector;
struct line{
	Point a, b;
	line() {}
	line(const Point &a,const Point &b) : a(a), b(b) {}
};

struct circle{
	Point c;
	double r;
	circle() : c(Point(0,0)), r(0) {}
	circle(const Point &c, double r) : c(c), r(r) {}
};
Point operator*(double c, const Point &a){ return Point(c * a.x, c * a.y); }
//Point operator/(const Point &a, const double c){ return Point(c * a.x, c * a.y); }
double abs(const Point &a){ return sqrt(a.x * a.x + a.y * a.y); }
Point rot(const Point &a, double theta){ return Point(a.x * cos(theta) - a.y * sin(theta), a.x * sin(theta) + a.y * cos(theta)); }
double arg(const Point &a){
	double t = atan2(a.y, a.x);
	return t < 0 ? t + 2 * Pi:t;
}
int tangent(const circle &C1,const circle &C2,vector<line> &res){
	double d = abs(C1.c - C2.c);
	if(d < eps) return 0;

	int c=0;
	if(C1.r + C2.r < d - eps){
		double t = acos((C1.r + C2.r) / d);
		res.push_back(line(C1.c + rot(C1.r / d * (C2.c - C1.c), t), C2.c + rot(C2.r / d * (C1.c - C2.c), t)));
		res.push_back(line(C1.c + rot(C1.r / d * (C2.c - C1.c),-t), C2.c + rot(C2.r / d * (C1.c - C2.c),-t)));
		c += 2;
	} else if(C1.r + C2.r < d + eps){
		Point p = C1.c + C1.r / d * (C2.c - C1.c);
		res.push_back(line(p, p + rot(C2.c - C1.c, Pi / 2)));
		c++;
	}

	if(abs(C1.r - C2.r) < d - eps){
		double t1 = acos((C1.r - C2.r) / d), t2 = Pi - t1;
		res.push_back(line(C1.c + rot(C1.r / d * (C2.c - C1.c), t1), C2.c + rot(C2.r / d * (C1.c - C2.c),-t2)));
		res.push_back(line(C1.c + rot(C1.r / d * (C2.c - C1.c),-t1), C2.c + rot(C2.r / d * (C1.c - C2.c), t2)));
		c+=2;
	} else if(abs(C1.r - C2.r) < d + eps){
		Point p = C1.c + C1.r / d * (C2.c - C1.c);
		res.push_back(line(p, p + rot(C2.c - C1.c, Pi / 2)));
		c++;
	}

	return c;
}

int n;
double maxn, minn, sima, simi;
double calc(double theta) {
	double tt[109] = {0};
	for(int k = 1; k <= n; k++) {
		tt[k] = rot(a[k], theta).y;
	}
	
	sort(tt + 1, tt + 1 + n);
	double mr = 0, sum = 0;
	sum = 2.0;
	mr = tt[1] + 1.0;
	for(int k = 1; k <= n; k++) {
		if(tt[k] + 1.0 < mr) continue;
		if(tt[k] - 1.0 < mr) {
			sum += tt[k] + 1.0 - mr;
		} else {
			sum += 2.0;
		}
		mr = tt[k] + 1.0;
	}
	return sum;
}
double calc_peak(double phi) {
	pair<double, int> p[109];
	for(int i = 1; i <= n; i++) {
		p[i] = make_pair(rot(a[i], phi).y, i);
	}
	sort(p + 1, p + 1 + n);
	int pre = 1;
	double x = 0, y = 0;
	for(int i = 2; i <= n + 1; i++) {
		if(i == n + 1 || p[i - 1].first + 1 < p[i].first - 1) {
			//dl/dw = d*cost*cosw - d*sint*sinw
			double d = abs(a[p[i - 1].second] - a[p[pre].second]);
			double t = arg(a[p[i - 1].second] - a[p[pre].second]);
			x += d * cos(t);
			y += d * sin(t);
			pre = i;
		}
	}
	double ans = arg({y, x});
	if(ans > Pi) ans -= Pi;
	return ans;
}

void work() {
	if(n == 0) exit(0);
	for(int i = 1; i <= n; i++) 
		scanf("%lf%lf", &a[i].x, &a[i].y);
	maxn = -1e18;
	minn = 1e18;
	vector<line> v;
	for(int i = 1; i <= n; i++) {
		for(int j = i + 1; j <= n; j++) {
			tangent(circle(a[i], 1.0), circle(a[j], 1.0), v);
		}
	}
	vector<double> th;
	for(int i = 0; i < v.size(); i++) {
		line &l = v[i];
		double tt = arg(l.b - l.a);
		if(tt < Pi) tt = Pi - tt;
		else tt = 2 * Pi - tt;
		th.push_back(tt);
	}
	th.push_back(0);
	th.push_back(Pi);
	sort(th.begin(), th.end());
	int tot = 0;
	for(int i = 0; i < th.size(); i++) 
		if(i == 0 || th[i] > th[i - 1] + eps) 
			th[tot++] = th[i];
	th.erase(th.begin() + tot, th.end());
	for(int i = 0; i < tot; i++) {
		double sum = calc(th[i]);
		if(sum > maxn + eps) {
			maxn = sum;
			sima = th[i];
		}
		if(sum < minn - eps) {
			minn = sum;
			simi = th[i];
		}
		if(i - 1 >= 0) {
			double phi0 = (th[i - 1] + th[i]) / 2;
			double phi1 = calc_peak(phi0);
			double sum = calc(phi1);
			if(sum > maxn + eps) {
				maxn = sum;
				sima = phi1;
			}
			if(sum < minn - eps) {
				minn = sum;
				simi = phi1;
			}
		}
	}
//	printf("%.15f %.15f\n", minn, maxn);
	printf("%.15f\n%.15f\n", simi, sima);
}
signed main()
{
//	freopen("data.in", "r", stdin);
	ios :: sync_with_stdio(0);
	cin.tie(0);
	while(~scanf("%d", &n)) work(); 
	return 0;
}
/*
枚举两个圆柱体相切的位置
 
*/
accuracy: 1
time_ms: 370
memory_kb: 5400
final_rank: 17

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
//#define EPS 0.000000001
using namespace std;



#define EPS 0.000000000001
#define SIZE 105

struct Point{
	Point(long double arg_x,long double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (long double a){ return Point(a*x,a*y); }
	Point operator / (long double a){ return Point(x/a,y/a); }

	long double abs(){ return sqrt(norm()); }
	long double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}


	void debug(){

		printf("(%.3Lf,%.3Lf)\n",x,y);
	}

	long double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}
	/*void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}*/
	Point p[2];
};

struct Circle{
	Point center,base_p;
	long double r;
};

struct Rad{
	Rad(long double arg_rad){

		rad = arg_rad;
	}
	bool operator<(const struct Rad &arg) const{

		return rad < arg.rad;
	}
	bool operator==(const struct Rad &arg) const{

		return fabs(rad-arg.rad) < EPS;
	}
	long double rad;
};


struct TAN_P{
	TAN_P(Point arg_p,bool arg_is_C1){
		p = arg_p;
		is_C1 = arg_is_C1;
	}
	Point p;
	bool is_C1;
};

struct Info{
	Info(Point arg_p,int arg_index){
		p = arg_p;
		index = arg_index;
	}
	bool operator<(const struct Info &arg) const{

		return p < arg.p;
	}
	Point p;
	int index;
};

int N;
long double R = 1.0;
long double NUM = 10000;
long double DIST[SIZE][SIZE];
Circle C[SIZE];


long double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

long double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

long double abs(Vector a){
	return sqrt(norm(a));
}

long double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

long double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw(Point p0,Point p1,Point p2){

	Vector a = p1 - p0;
	Vector b = p2 - p0;

	if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
	if(cross(a,b) < -EPS)return CLOCKWISE;
	if(dot(a,b) < -EPS)return ONLINE_BACK;
	if(a.norm() < b.norm())return ONLINE_FRONT;

	return ON_SEGMENT;
}

long double calc_slope(Line A){

	if(fabs(A.p[0].x-A.p[1].x) < EPS){

		return DBL_MAX;

	}else if(fabs(A.p[0].y-A.p[1].y) < EPS){

		return 0;

	}else{

		return (A.p[1].y-A.p[0].y)/(A.p[1].x-A.p[0].x);
	}
}




//C1,C2の接点を返却する関数
vector<TAN_P> getContact(Circle C1,Circle C2){

	vector<TAN_P> ret;

	for(int loop = 0; loop < 2; loop++){

		long double p = C2.center.x-C1.center.x;
		long double q = C2.center.y-C1.center.y;

		long double A = p*p+q*q;

		long double n_1 = (q*C1.r*(C1.r+C2.r)-p*C1.r*sqrt(A-(C1.r+C2.r)*(C1.r+C2.r)))/(A)+C1.center.y;
		long double n_2 = (q*C1.r*(C1.r+C2.r)+p*C1.r*sqrt(A-(C1.r+C2.r)*(C1.r+C2.r)))/(A)+C1.center.y;

		long double m_1 = (p*C1.r*(C1.r+C2.r)+q*C1.r*sqrt(A-(C1.r+C2.r)*(C1.r+C2.r)))/(A)+C1.center.x;
		long double m_2 = (p*C1.r*(C1.r+C2.r)-q*C1.r*sqrt(A-(C1.r+C2.r)*(C1.r+C2.r)))/(A)+C1.center.x;

		if(A-(C1.r+C2.r)*(C1.r+C2.r) >= 0){
			ret.push_back(TAN_P(Point(m_1,n_1),loop == 0));
			ret.push_back(TAN_P(Point(m_2,n_2),loop == 0));
		}

		long double n_3 = (q*C1.r*(C1.r-C2.r)-p*C1.r*sqrt(A-(C1.r-C2.r)*(C1.r-C2.r)))/(A)+C1.center.y;
		long double n_4 = (q*C1.r*(C1.r-C2.r)+p*C1.r*sqrt(A-(C1.r-C2.r)*(C1.r-C2.r)))/(A)+C1.center.y;

		long double m_3 = (p*C1.r*(C1.r-C2.r)+q*C1.r*sqrt(A-(C1.r-C2.r)*(C1.r-C2.r)))/(A)+C1.center.x;
		long double m_4 = (p*C1.r*(C1.r-C2.r)-q*C1.r*sqrt(A-(C1.r-C2.r)*(C1.r-C2.r)))/(A)+C1.center.x;

		if(A-(C1.r-C2.r)*(C1.r-C2.r) >= 0){
			ret.push_back(TAN_P(Point(m_3,n_3),loop==0));
			ret.push_back(TAN_P(Point(m_4,n_4),loop==0));
		}

		swap(C1,C2);
	}

	return ret;
}

//点のradを求める関数
long double calc_rad(Point p){

	if(p.y == 0){

		if(p.x > 0){

			return 0;

		}else{ //p.x < 0

			return M_PI;
		}

	}else if(p.x == 0){

		if(p.y > 0){

			return M_PI/2.0;
		}else{


			return 3*M_PI/2.0;
		}

	}else{

		long double base = atan(fabs(p.y)/fabs(p.x));

		if(p.x > 0){

			if(p.y > 0){

				return base;

			}else{ //p.y < 0

				return 2*M_PI-base;
			}

		}else{ //p.x < 0

			if(p.y > 0){

				return M_PI-base;

			}else{

				return base+M_PI;
			}
		}
	}
}


int func(long double x1,long double y1,long double x2, long double y2, long double xp, long double yp){
	long double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


//★★直線ではなく、線分の交差判定★★
bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

long double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

//線分ではなく直線と点の距離
long double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//点と線分の距離
long double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

bool on_arc(Circle C1,Point p){

	return fabs(calc_dist(C1.center,p)-C1.r) < EPS;
}

bool contain_check(Circle C1,Line tmp_line){

	if(getDistanceSP(tmp_line,C1.center)+EPS < C1.r){

		return true;
	}else{

		return false;
	}
}


//交点を求める関数
Point calc_Cross_Point(long double x1,long double x2,long double x3,long double x4,long double y1,long double y2,long double y3,long double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(fabs(x1-x2) > EPS){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(getDistanceSP(B,A.p[0]) < EPS){

		return A.p[0];

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return A.p[1];

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return B.p[0];

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return B.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}


//点pを通る傾きtan(rad)の直線とy = -(1/tan(rad))x+kの交点を求める
Point calc_point(Point p,double rad){

	long double slope1 = tan(rad);

	Line line1 = Line(Point(p.x-NUM,p.y-NUM*slope1),Point(p.x+NUM,p.y+NUM*slope1));


	long double slope2 = -(1.0/slope1);

	Line line2 = Line(Point(-NUM,-NUM*slope2),Point(NUM,NUM*slope2));

	return calc_Cross_Point(line1,line2);
}

//2つのvectorがなすラジアンを求める関数
long double calc_rad(Vector vec1,Vector vec2){

	long double tmp = dot(vec1,vec2)/(abs(vec1)*abs(vec2));

	if(fabs(tmp+1.0) < EPS){

		return M_PI;
	}

	if(fabs(tmp-1.0) < EPS){

		return  0.0;
	}

	return acos(dot(vec1,vec2)/(abs(vec1)*abs(vec2)));
}

//3点がなすラジアンを求める関数(ccw(base,a,b) == CCW)
long double calc_rad(Point base,Point a,Point b){

	Vector vec1 = b-base;
	Vector vec2 = a-base;

	return calc_rad(vec1,vec2);
}



//θ=baseの近くで微分する
long double calc_rad(long double base){

	vector<Info> info;

	for(int i = 0; i < N; i++){

		info.push_back(Info(calc_point(C[i].center,base),i));
	}

	sort(info.begin(),info.end());

	long double A = 0,B = 0;

	for(int i = 1; i < info.size(); i++){

		if(calc_dist(info[i-1].p,info[i].p) > 2*R+EPS)continue;

		long double tmp_dist = DIST[info[i-1].index][info[i].index];
		long double tmp_rad;

		if(ccw(C[info[i].index].center,C[info[i].index].base_p,C[info[i-1].index].center) == COUNTER_CLOCKWISE){

			tmp_rad = calc_rad(C[info[i].index].center,C[info[i].index].base_p,C[info[i-1].index].center);

		}else{

			tmp_rad = 2*M_PI-calc_rad(C[info[i].index].center,C[info[i-1].index].center,C[info[i].index].base_p);
		}

		A += tmp_dist*sin(tmp_rad);
		B += tmp_dist*cos(tmp_rad);
	}

	long double ret = calc_rad(Point(A,-B));


	if(ret > M_PI){
		ret -= M_PI;
	}
	return ret;
}


long double calc_len(long double rad){

	vector<Point> V;
	long double ret = 2.0;

	if(fabs(rad) < EPS || fabs(rad-M_PI) < EPS){

		for(int i = 0; i < N; i++){

			V.push_back(Point(0,C[i].center.y));
		}
	}else if(fabs(rad-M_PI/2.0) < EPS){

		for(int i = 0; i < N; i++){

			V.push_back(Point(C[i].center.x,0));
		}

	}else{

		for(int i = 0; i < N; i++){

			V.push_back(calc_point(C[i].center,rad));
		}
	}

	sort(V.begin(),V.end());

	long double L = 2;

	for(int i = 1; i < V.size(); i++){

		ret += min(L,calc_dist(V[i],V[i-1]));
	}

	return ret;
}

void func(){

	for(int i = 0; i < N; i++){

		scanf("%Lf %Lf",&C[i].center.x,&C[i].center.y);
		C[i].r = R;
		C[i].base_p = Point(C[i].center.x+10,C[i].center.y);
	}
	if(N == 1){

		printf("0.000000000000000\n");
		printf("0.000000000000000\n");
		return;
	}

	vector<Rad> RAD;
	RAD.push_back(Rad(0));
	RAD.push_back(Rad(M_PI/2.0)); //cos(θ)が0
	RAD.push_back(Rad(M_PI));

	long double tmp_x = 10; //rad計算用
	long double tmp_y;

	Circle C1,C2;

	Vector tmp_vec,vec_i,vec_k;


	for(int i = 0; i < N-1; i++){
		for(int k = i+1; k < N; k++){

			DIST[i][k] = calc_dist(C[i].center,C[k].center);
			DIST[k][i] = DIST[i][k];

			vector<TAN_P> v_tan = getContact(C[i],C[k]);
			for(int a = 0; a < v_tan.size()-1; a++){
				if(!v_tan[a].is_C1 || !on_arc(C[i],v_tan[a].p))continue;
				for(int b = a+1; b < v_tan.size(); b++){
					if(v_tan[b].is_C1 || !on_arc(C[k],v_tan[b].p))continue;

					Line tmp_line = Line(v_tan[a].p,v_tan[b].p);
					if(contain_check(C1,tmp_line) || contain_check(C2,tmp_line))continue;

					tmp_vec = v_tan[a].p-v_tan[b].p;
					vec_i = v_tan[a].p-C[i].center;
					vec_k = v_tan[b].p-C[k].center;

					if(fabs(dot(tmp_vec,vec_i) > EPS || fabs(dot(tmp_vec,vec_k)) > EPS))continue;

					long double tmp_slope = calc_slope(tmp_line);
					tmp_y = tmp_x*tmp_slope;
					long double tmp_rad = calc_rad(Point(tmp_x,tmp_y));

					//★注意★
					if(tmp_rad > M_PI+EPS){

						tmp_rad -= M_PI;
					}
					//★★★★y = xのradをπ/4とする方向で、解を保存する段階で帳尻を合わせる★★★★

					RAD.push_back(Rad(tmp_rad));
				}
			}
		}
	}

	sort(RAD.begin(),RAD.end());
	RAD.erase(unique(RAD.begin(),RAD.end()),RAD.end());

	long double max_len = -BIG_NUM,min_len = BIG_NUM;
	long double max_rad,min_rad;

	long double tmp_len;

	for(int i = 0; i < RAD.size(); i++){

		if(i > 0){
			tmp_len = calc_len(RAD[i].rad);
			if(tmp_len > max_len+EPS){

				max_len = tmp_len;
				max_rad = M_PI-RAD[i].rad;
			}
			if(tmp_len+EPS < min_len){
				min_len = tmp_len;
				min_rad = M_PI-RAD[i].rad;
			}
		}

		if(i == RAD.size()-1)break;

		long double tmp_rad = (RAD[i].rad+RAD[i+1].rad);
		tmp_rad = calc_rad(tmp_rad);

		tmp_len = calc_len(tmp_rad);

		if(tmp_len > max_len+EPS){
			max_len = tmp_len;
			max_rad = M_PI-tmp_rad;
		}
		if(tmp_len+EPS < min_len){
			min_len = tmp_len;
			min_rad = M_PI-tmp_rad;
		}
	}

	printf("%.15Lf\n",min_rad);
	printf("%.15Lf\n",max_rad);
}

int main(){

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 4400
memory_kb: 4460
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <iomanip>
#include <cmath>
using namespace std;
const double EPS = 1e-12;
const double INF = 1e18;
const double PI = acos(-1);

//range : [-PI/2, PI/2]
vector<double> special_angle(vector<double> &x, vector<double> &y){
    int n = x.size();
    vector<double> ret;
    for(int i=0; i<n; i++){
        for(int j=i+1; j<n; j++){
            double narg[2];
            double a = x[i] -x[j];
            double b = y[i] -y[j];
            //中心が重なる角度
            narg[0] = (abs(a) < EPS)? PI/2 : atan(-b/a);
            ret.push_back(narg[0]);
            //端が重なる角度
            if(abs(a) < EPS){
            	narg[0] = acos(2/b);
            	narg[1] = acos(-2/b);
            }else{
            	narg[0] = asin(2/sqrt(a*a +b*b)) -atan(b/a);
            	narg[1] = asin(-2/sqrt(a*a +b*b)) -atan(b/a);
            }
            for(int k=0; k<2; k++){
                while(narg[k] < -PI/2) narg[k] += PI;
                while(narg[k] > PI/2) narg[k] -= PI;
                ret.push_back(narg[k]);
            }
        }
    }
    
    ret.push_back(PI/2);
    ret.push_back(0);
    ret.push_back(-PI/2);
    sort(ret.begin(), ret.end());
    ret.erase(unique(ret.begin(), ret.end()), ret.end());
    return ret;
}

vector<double> projection(double angle, vector<double> &x, vector<double> &y){
	int n = x.size();
	vector<double> ret(n);
	for(int i=0; i<n; i++){
		ret[i] = x[i]*sin(angle) +y[i]*cos(angle);
	}
    return ret;
}

vector<int> getorder(double angle, vector<double> &x, vector<double> &y){
    int n = x.size();
    vector<int> ret(n);
    vector<double> dist = projection(angle, x, y);
    vector<pair<double, int> > ord(n);
    for(int i=0; i<n; i++){
        ord[i] = make_pair(dist[i], i);
    }
    sort(ord.begin(), ord.end());
    for(int i=0; i<n; i++){
        ret[i] = ord[i].second;
    }
    return ret;
}

double getwidth(double angle, vector<double> &x, vector<double> &y){
    vector<int> order = getorder(angle, x, y);
    vector<double> dist = projection(angle, x, y);
    double ret = 2;
    for(int i=0; i<(int)x.size()-1; i++){
    	double d = dist[order[i+1]] -dist[order[i]];
        if(d < 2) ret += d;
        else ret += 2;
    }
    return ret;
}

pair<double, double> solve(vector<double> &x, vector<double> &y){
    vector<double> angle = special_angle(x, y);
    vector<pair<double, double> > cand; //pair<angle, width>
    
    for(int i=0; i<(int)angle.size(); i++){
        cand.push_back(make_pair(angle[i], getwidth(angle[i], x, y)));
    }
    for(int i=0; i<(int)angle.size()-1; i++){
        double mid = (angle[i] +angle[i+1])/2;
        vector<int> order = getorder(mid, x, y);
        vector<double> dist = projection(mid, x, y);
        //f(t) = a*sin(t) +b*cos(t) +c
        double a=0, b=0;
        for(int j=0; j<(int)x.size()-1; j++){
        	double d = dist[order[j+1]] -dist[order[j]];
        	if(d < 2){
        		a += x[order[j+1]] -x[order[j]];
        		b += y[order[j+1]] -y[order[j]];
        	}
        }
        //f'(t) = a*cos(t) -b*sin(t) = 0 より
        //tan(t) = a/b
        if(abs(b) < EPS) continue;
        double theta = atan(a/b);
        if(angle[i] -EPS < theta && theta < angle[i+1] +EPS){
        	cand.push_back(make_pair(theta, getwidth(theta, x, y)));
        }
    }
    
    double wmin=INF, wmax=0;
    double amin=INF, amax=INF;
    for(int i=0; i<(int)cand.size(); i++){
        double theta = cand[i].first;
        double width = cand[i].second;
        if(width < wmin){
            wmin = width;
            amin = theta;
        }
        if(width > wmax){
            wmax = width;
            amax = theta;
        }
    }
    
    //[0, PI]に変換
    if(abs(amin)<EPS) amin = 0;
    if(abs(amax)<EPS) amax = 0;
    if(amin < 0) amin += PI;
    if(amax < 0) amax += PI;
    return make_pair(amin, amax);
}

int main(){
    while(1){
        int n;
        cin >> n;
        if(n==0) break;
        
        vector<double> x(n),y(n);
        for(int i=0; i<n; i++){
            cin >> x[i] >> y[i];
        }
        pair<double, double> ans = solve(x, y);
        cout << fixed;
        cout << setprecision(12);
        cout << ans.first << endl << ans.second << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3828
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;

using F = double;

struct Point {F x, y;};

const F PI = acos(-1);
const F INF = 1e9;

int N;
vector<Point> P;

F tune(auto a) {
  while(a  < 0) a += PI;
  while(PI < a) a -= PI;
  return a;
}

F projection(auto p, auto a) {
  return p.x * sin(a) + p.y * cos(a);
}

tuple<F, F, F> coefficient(auto a) {
  vector<pair<F, int>> lx;
  for(auto i = 0; i < P.size(); ++i) lx.emplace_back(projection(P[i], a) - 1, i);
  sort(begin(lx), end(lx));

  vector<pair<int, int>> shadow;
  shadow.emplace_back(lx.front().second, lx.front().second);
  for(auto i: lx) {
    auto rx = projection(P[shadow.back().second], a) + 1;
    if(rx < i.first) shadow.emplace_back(i.second, i.second);
    else             shadow.back().second = i.second;
  }

  F A = 0, B = 0, C = 0;
  for(auto s: shadow) {
    auto l = P[s.first];
    auto r = P[s.second];
    A += r.x - l.x;
    B += r.y - l.y;
    C += 1   - -1;
  }
  return make_tuple(A, B, C);
}

vector<F> solve() {
  vector<F> angle = {0, PI};
  for(auto j = 0; j < N; ++j) for(auto i = 0; i < j; ++i) {
    auto dx = P[i].x - P[j].x;
    auto dy = P[i].y - P[j].y;
    auto d = hypot(dx, dy);
    auto a = atan2(dy, dx);
    angle.emplace_back(tune(-a));
    angle.emplace_back(tune(asin(2 / d)  - a));
    angle.emplace_back(tune(asin(-2 / d) - a));
  }
  sort(begin(angle), end(angle));
  angle.erase(unique(begin(angle), end(angle)), end(angle));

  F a_min = INF, a_max = -INF;
  F s_min = INF, s_max = -INF;
  for(auto i = 1; i < angle.size(); ++i) {
    auto low  = angle[i - 1];
    auto high = angle[i];
    auto middle = (low + high) / 2;

    F a, b, c;
    tie(a, b, c) = coefficient(middle);

    for(auto i: {low, tune(PI / 2 - atan2(b, a))}) if(low <= i && i <= high) {
      auto s = a * sin(i) + b * cos(i) + c;
      if(s_min > s) {
        s_min = s;
        a_min = i;
      }
      if(s_max < s) {
        s_max = s;
        a_max = i;
      }
    }
  }

  return {a_min, a_max};
}

int main() {
  while(cin >> N, N) {
    P = vector<Point>(N);
    for(auto& i: P) cin >> i.x >> i.y;

    for(auto i: solve()) cout << setprecision(15) << fixed << i << endl;
  }
}
accuracy: 1
time_ms: 180
memory_kb: 3884
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;

using F = double;

struct Point {F x, y;};
struct Interval {
  F lx, rx;
  int l, r;
  Interval(F lx, F rx, int l, int r) : lx(lx), rx(rx), l(l), r(r) {}
  bool operator<(auto o) const {
    if(lx != o.lx) return lx < o.lx;
    if(rx != o.rx) return rx < o.rx;
    if(l != o.l) return l < o.l;
    return r < o.r;
  }
};

const F PI = acos(-1);
const F INF = 1e9;

int N;
vector<Point> P;

F tune(auto a) {
  while(a  < 0) a += PI;
  while(PI < a) a -= PI;
  return a;
}

F projection(auto p, auto a) {
  return p.x * sin(a) + p.y * cos(a);
}

tuple<F, F, F> coefficient(auto a) {
  vector<pair<F, int>> lx;
  for(auto i = 0; i < P.size(); ++i) lx.emplace_back(projection(P[i], a) - 1, i);
  sort(begin(lx), end(lx));

  vector<pair<int, int>> shadow;
  shadow.emplace_back(lx.front().second, lx.front().second);
  for(auto i: lx) {
    auto rx = projection(P[shadow.back().second], a) + 1;
    if(rx < i.first) shadow.emplace_back(i.second, i.second);
    else             shadow.back().second = i.second;
  }

  F A = 0, B = 0, C = 0;
  for(auto s: shadow) {
    auto l = P[s.first];
    auto r = P[s.second];
    A += r.x - l.x;
    B += r.y - l.y;
    C += 1   - -1;
  }
  return make_tuple(A, B, C);
}

vector<F> solve() {
  vector<F> angle = {0, PI};
  for(auto j = 0; j < N; ++j) for(auto i = 0; i < j; ++i) {
    auto dx = P[i].x - P[j].x;
    auto dy = P[i].y - P[j].y;
    auto d = hypot(dx, dy);
    auto a = atan2(dy, dx);
    angle.emplace_back(tune(-a));
    angle.emplace_back(tune(asin(2 / d)  - a));
    angle.emplace_back(tune(asin(-2 / d) - a));
  }
  sort(begin(angle), end(angle));
  angle.erase(unique(begin(angle), end(angle)), end(angle));

  F a_min = INF, a_max = -INF;
  F s_min = INF, s_max = -INF;
  for(auto i = 1; i < angle.size(); ++i) {
    auto low  = angle[i - 1];
    auto high = angle[i];
    auto middle = (low + high) / 2;

    F a, b, c;
    tie(a, b, c) = coefficient(middle);

    for(auto i: {low, tune(PI / 2 - atan2(b, a))}) if(low <= i && i <= high) {
      auto s = a * sin(i) + b * cos(i) + c;
      if(s_min > s) {
        s_min = s;
        a_min = i;
      }
      if(s_max < s) {
        s_max = s;
        a_max = i;
      }
    }
  }

  return {a_min, a_max};
}

int main() {
  while(cin >> N, N) {
    P = vector<Point>(N);
    for(auto& i: P) cin >> i.x >> i.y;

    for(auto i: solve()) cout << setprecision(15) << fixed << i << endl;
  }
}
accuracy: 1
time_ms: 180
memory_kb: 3808
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;

using F = double;

struct Point {F x, y;};
struct Interval {
  F lx, rx;
  int l, r;
  Interval(F lx, F rx, int l, int r) : lx(lx), rx(rx), l(l), r(r) {}
  bool operator<(auto o) const {
    if(lx != o.lx) return lx < o.lx;
    if(rx != o.rx) return rx < o.rx;
    if(l != o.l) return l < o.l;
    return r < o.r;
  }
};

const F PI = acos(-1);
const F INF = 1e9;

int N;
vector<Point> P;

F tune(auto a) {
  while(a  < 0) a += PI;
  while(PI < a) a -= PI;
  return a;
}

F projection(auto p, auto a) {
  return p.x * sin(a) + p.y * cos(a);
}

tuple<F, F, F> coefficient(auto a) {
  vector<pair<F, int>> lx;
  for(auto i = 0; i < P.size(); ++i) lx.emplace_back(projection(P[i], a) - 1, i);
  sort(begin(lx), end(lx));

  vector<pair<int, int>> shadow;
  shadow.emplace_back(lx.front().second, lx.front().second);
  for(auto i: lx) {
    auto rx = projection(P[shadow.back().second], a) + 1;
    if(rx < i.first) shadow.emplace_back(i.second, i.second);
    else             shadow.back().second = i.second;
  }

  F A = 0, B = 0, C = 0;
  for(auto s: shadow) {
    auto l = P[s.first];
    auto r = P[s.second];
    A += r.x - l.x;
    B += r.y - l.y;
    C += 1 - -1;
  }
  return make_tuple(A, B, C);
}

vector<F> solve() {
  vector<F> angle = {0, PI};
  for(auto j = 0; j < N; ++j) for(auto i = 0; i < j; ++i) {
    auto dx = P[i].x - P[j].x;
    auto dy = P[i].y - P[j].y;
    auto d = hypot(dx, dy);
    auto a = atan2(dy, dx);
    angle.emplace_back(tune(-a));
    angle.emplace_back(tune(asin(2 / d) - a));
    angle.emplace_back(tune(asin(-2 / d) - a));
  }
  sort(begin(angle), end(angle));
  angle.erase(unique(begin(angle), end(angle)), end(angle));

  F a_min = INF, a_max = -INF;
  F s_min = INF, s_max = -INF;
  for(auto i = 1; i < angle.size(); ++i) {
    auto low  = angle[i - 1];
    auto high = angle[i];
    auto middle = (low + high) / 2;

    F a, b, c;
    tie(a, b, c) = coefficient(middle);

    for(auto i: {low, tune(PI / 2 - atan2(b, a)), high}) if(low <= i && i <= high) {
      auto s = a * sin(i) + b * cos(i) + c;
      if(s_min > s) {
        s_min = s;
        a_min = i;
      }
      if(s_max < s) {
        s_max = s;
        a_max = i;
      }
    }
  }

  return {a_min, a_max};
}

int main() {
  while(cin >> N, N) {
    P = vector<Point>(N);
    for(auto& i: P) cin >> i.x >> i.y;

    for(auto i: solve()) cout << setprecision(15) << fixed << i << endl;
  }
}
accuracy: 1
time_ms: 180
memory_kb: 3832
final_rank: 5

code_snippet: #include <bits/stdc++.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) (sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg)),arg)

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using namespace std;
using R=long double;

int n,x[110],y[110];

using R=long double;
const R PI = acos(R(-1));
const R INF = 1e40;
using P=complex<R>;
using C=tuple<R,R,R>;
#define mod(x,y) fmod(fmod(x,y)+y,y)

inline C shadow(R theta){
	R a=0.0,b=0.0,c=2.0*n;

	using state=tuple<R,int>;
	vector<state> ary;

	rep(i,n) ary.push_back(make_tuple(1.0*x[i]*sin(theta)+1.0*y[i]*cos(theta),i));
	sort(_all(ary));
	
	rep(i,n-1){
		R cur,nxt; int idx,idx2;
		tie(cur,idx)=ary[i],tie(nxt,idx2)=ary[i+1];
		if(nxt-cur<2.0){
			c-=2.0;
			a+=(x[idx2]-x[idx]),b+=(y[idx2]-y[idx]);
		}
	}
	return make_tuple(a,b,c);
}

int main(void){
	while(cin >> n,n){		
		vector<R> candiate={0.0,PI/2.0,PI};
		rep(i,n) cin >> x[i] >> y[i];
		cout.precision(20);

		rep(j,n)rep(i,j){
			P a=P(x[i],y[i]),b=P(x[j],y[j]);
			R c=arg(b-a),e=asin(2.0/abs(b-a));
			candiate.push_back(mod(PI-c,PI));
			candiate.push_back(mod(PI-c+e,PI));
			candiate.push_back(mod(PI-c-e,PI));
		}

		uniq(candiate);
		candiate.push_back(candiate[0]+PI);	
		int m=int(candiate.size());

		rep(i,m-1){
			R cur=candiate[i],nxt=candiate[i+1],a,b,c;
			tie(a,b,c)=shadow((cur+nxt)/2.0);
			R theta=mod(atan(a/b),PI);
			if(cur < mod(theta,PI) && mod(theta,PI) < nxt) candiate.push_back(mod(theta,PI));
		}	

		R cmin=INF,theta1=-1.0;
		for(auto &theta:candiate){
			R a,b,c;
			tie(a,b,c)=shadow(theta);
			if(chmin(cmin,a*sin(theta)+b*cos(theta)+c)) theta1=theta;
		}
		cout << fixed << theta1 << endl;
		
		R cmax=0.0,theta2=-1.0;
		for(auto &theta:candiate){
			R a,b,c;
			tie(a,b,c)=shadow(theta);
			if(chmax(cmax,a*sin(theta)+b*cos(theta)+c)) theta2=theta;
		}
		cout << fixed << theta2 << endl;

	}
	return 0;
}
accuracy: 1
time_ms: 830
memory_kb: 3796
final_rank: 11

code_snippet: #include <bits/stdc++.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) (sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg)),arg)

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using namespace std;
using R=long double;

int n,x[110],y[110];

using R=long double;
constexpr R PI = acos(R(-1));
constexpr R INF = 1e40;
using P=complex<R>;
using C=tuple<R,R,R>;
#define mod(x,y) fmod(fmod(x,y)+y,y)


inline C shadow(R theta){
	R a=0.0,b=0.0,c=0.0;
	R vx=sin(theta),vy=cos(theta);

	using state=tuple<R,int>;
	vector<state> ary;

	rep(i,n) ary.push_back(make_tuple(1.0*x[i]*vx+1.0*y[i]*vy,i));
	sort(_all(ary));
	
	c+=2.0*n;

	rep(i,n-1){
		R cur,nxt; int idx,idx2;
		tie(cur,idx)=ary[i],tie(nxt,idx2)=ary[i+1];
		if(nxt-cur<2.0){
			c-=2.0;
			a+=(x[idx2]-x[idx]),b+=(y[idx2]-y[idx]);
		}
	}
	return make_tuple(a,b,c);
}

int main(void){
	while(cin >> n,n){		
		vector<R> candiate={0.0,PI/2.0,PI};
		rep(i,n) cin >> x[i] >> y[i];
		cout.precision(20);


		rep(j,n)rep(i,j){
			P a=P(x[i],y[i]),b=P(x[j],y[j]);
			R c=arg(b-a),e=asin(2.0/abs(b-a));
			candiate.push_back(mod(PI-c,PI));
			candiate.push_back(mod(PI-c+e,PI));
			candiate.push_back(mod(PI-c-e,PI));
		}

		uniq(candiate);
		candiate.push_back(candiate[0]+PI);	
		int m=int(candiate.size());

		rep(i,m-1){
			R cur=candiate[i],nxt=candiate[i+1],a,b,c;
			tie(a,b,c)=shadow((cur+nxt)/2.0);
			R theta=mod(atan(a/b),PI);
			if(cur < mod(theta,PI) && mod(theta,PI) < nxt) candiate.push_back(mod(theta,PI));
		}	

		R cmin=INF,theta1=-1.0;
		for(auto &theta:candiate){
			R a,b,c;
			tie(a,b,c)=shadow(theta);
			if(chmin(cmin,a*sin(theta)+b*cos(theta)+c)) theta1=theta;
		}
		cout << fixed << theta1 << endl;
		
		R cmax=0.0,theta2=-1.0;
		for(auto &theta:candiate){
			R a,b,c;
			tie(a,b,c)=shadow(theta);
			if(chmax(cmax,a*sin(theta)+b*cos(theta)+c)) theta2=theta;
		}
		cout << fixed << theta2 << endl;

	}
	return 0;
}
accuracy: 1
time_ms: 780
memory_kb: 3908
final_rank: 12

code_snippet: #include <iostream>
#include <iomanip>
#include <cmath>
#include <complex>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;

typedef double D;
typedef complex<D> P;
typedef pair<D,int> pdi;

D pi;
D smax, smin, tmax, tmin;
vector<P> ps;

D dot(const P &a, const P &b){
	return real(a) * real(b) + imag(a) * imag(b);
}

P check(D t){
	while(t < 0.0){ t += pi; }
	while(t >= pi){ t -= pi; }
	t += 0.0;
	
	int n = ps.size();
	P a = polar(D(1.0), 0.5 * pi - t);
	vector<pdi> v(2 * n);
	for(int i = 0; i < n; ++i){
		D z = dot(ps[i], a);
		v[2 * i] = pdi(z - 1.0, i);
		v[2 * i + 1] = pdi(z + 1.0, ~i);
	}
	sort(v.begin(), v.end());
	int cnt = 0;
	D sum = 0.0;
	P ret;
	for(int i = 0; i < 2 * n; ++i){
		if(cnt){ sum += v[i].first - v[i - 1].first; }
		if(v[i].second >= 0){
			if(!cnt++){ ret -= ps[v[i].second]; }
		}
		else{
			if(!--cnt){ ret += ps[~v[i].second]; }
		}
	}
	
	if(sum > smax){
		smax = sum;
		tmax = t;
	}
	if(sum < smin){
		smin = sum;
		tmin = t;
	}

	return ret;
}

int main(){
	pi = acos(D(-1.0));
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(10);

	int n;
	while(cin >> n, n){
		smax = -1e300;
		smin = 1e300;
	
		ps.resize(n);
		for(int i = 0; i < n; ++i){
			int x, y;
			cin >> x >> y;
			ps[i] = P(x, y);
		}

		check(0);

		vector<D> cand;
		for(int i = 0; i < n; ++i)
		for(int j = 0; j < i; ++j){
			D a = -arg(ps[j] - ps[i]);
			D b = asin(2.0 / abs(ps[j] - ps[i]));
			cand.push_back(a);
			cand.push_back(a - b);
			cand.push_back(a + b);
		}
		for(size_t i = 0; i < cand.size(); ++i){
			while(cand[i] < 0.0){ cand[i] += pi; }
			while(cand[i] > pi){ cand[i] -= pi; }
			check(cand[i]);
		}
		sort(cand.begin(), cand.end());
		for(size_t i = 1; i < cand.size(); ++i){
			P ret = check(0.5 * (cand[i - 1] + cand[i]));
			if(abs(ret) > 1e-10){
				check(0.5 * pi - arg(ret));
			}
		}

		tmin = min(tmin, pi - 1e-10);
		tmax = min(tmax, pi - 1e-10);
		cout << tmin << '\n' << tmax << '\n';
	}
}
accuracy: 1
time_ms: 2720
memory_kb: 1552
final_rank: 9

code_snippet: #include <iostream>
#include <iomanip>
#include <cmath>
#include <complex>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;

typedef double D;
typedef complex<D> P;
typedef pair<D,int> pdi;

D pi;
D smax, smin, tmax, tmin;
vector<P> ps;

D dot(const P &a, const P &b){
	return real(a) * real(b) + imag(a) * imag(b);
}

P check(D t){
	while(t < 0.0){ t += pi; }
	while(t >= pi){ t -= pi; }
	t += 0.0;
	
	int n = ps.size();
	P a = polar(D(1.0), 0.5 * pi - t);
	vector<pdi> v(2 * n);
	for(int i = 0; i < n; ++i){
		D z = dot(ps[i], a);
		v[2 * i] = pdi(z - 1.0, i);
		v[2 * i + 1] = pdi(z + 1.0, ~i);
	}
	sort(v.begin(), v.end());
	int cnt = 0;
	D sum = 0.0;
	P ret;
	for(int i = 0; i < 2 * n; ++i){
		if(cnt){ sum += v[i].first - v[i - 1].first; }
		if(v[i].second >= 0){
			if(!cnt++){ ret -= ps[v[i].second]; }
		}
		else{
			if(!--cnt){ ret += ps[~v[i].second]; }
		}
	}
	
	if(sum > smax){
		smax = sum;
		tmax = t;
	}
	if(sum < smin){
		smin = sum;
		tmin = t;
	}

	return ret;
}

int main(){
	pi = acos(D(-1.0));
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(10);

	int n;
	while(cin >> n, n){
		smax = -1e300;
		smin = 1e300;
	
		ps.resize(n);
		for(int i = 0; i < n; ++i){
			int x, y;
			cin >> x >> y;
			ps[i] = P(x, y);
		}

		check(0);

		vector<D> cand;
		for(int i = 0; i < n; ++i)
		for(int j = 0; j < i; ++j){
			D a = -arg(ps[j] - ps[i]);
			D b = asin(2.0 / abs(ps[j] - ps[i]));
			cand.push_back(a);
			cand.push_back(a - b);
			cand.push_back(a + b);
		}
		for(size_t i = 0; i < cand.size(); ++i){
			while(cand[i] < 0.0){ cand[i] += pi; }
			while(cand[i] > pi){ cand[i] -= pi; }
			check(cand[i]);
		}
		sort(cand.begin(), cand.end());
		for(size_t i = 1; i < cand.size(); ++i){
			P ret = check(0.5 * (cand[i - 1] + cand[i]));
			if(abs(ret) > 1e-12){
				check(0.5 * pi - arg(ret));
			}
		}
		cout << tmin << '\n' << tmax << '\n';
	}
}
accuracy: 1
time_ms: 2630
memory_kb: 1548
final_rank: 8

code_snippet: #include <iostream>
#include <iomanip>
#include <cmath>
#include <complex>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;

typedef double D;
typedef complex<D> P;
typedef pair<D,int> pdi;

D pi;
D smax, smin, tmax, tmin;
vector<P> ps;

D dot(const P &a, const P &b){
	return real(a) * real(b) + imag(a) * imag(b);
}

P check(D t){
	while(t < 0.0){ t += pi; }
	while(t >= pi){ t -= pi; }
	t += 0.0;
	
	int n = ps.size();
	P a = polar(D(1.0), 0.5 * pi - t);
	vector<pdi> v(2 * n);
	for(int i = 0; i < n; ++i){
		D z = dot(ps[i], a);
		v[2 * i] = pdi(z - 1.0, i);
		v[2 * i + 1] = pdi(z + 1.0, ~i);
	}
	sort(v.begin(), v.end());
	int cnt = 0;
	D sum = 0.0;
	P ret;
	for(int i = 0; i < 2 * n; ++i){
		if(cnt){ sum += v[i].first - v[i - 1].first; }
		if(v[i].second >= 0){
			if(!cnt++){ ret -= ps[v[i].second]; }
		}
		else{
			if(!--cnt){ ret += ps[~v[i].second]; }
		}
	}
	
	if(sum > smax){
		smax = sum;
		tmax = t;
	}
	if(sum < smin){
		smin = sum;
		tmin = t;
	}

	return ret;
}

int main(){
	pi = acos(D(-1.0));
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(10);

	int n;
	while(cin >> n, n){
		smax = -1e300;
		smin = 1e300;
	
		ps.resize(n);
		for(int i = 0; i < n; ++i){
			int x, y;
			cin >> x >> y;
			ps[i] = P(x, y);
		}

		check(0);

		vector<D> cand;
		for(int i = 0; i < n; ++i)
		for(int j = 0; j < i; ++j){
			D a = -arg(ps[j] - ps[i]);
			D b = asin(2.0 / abs(ps[j] - ps[i]));
			cand.push_back(a);
			cand.push_back(a - b);
			cand.push_back(a + b);
		}
		for(size_t i = 0; i < cand.size(); ++i){
			while(cand[i] < 0.0){ cand[i] += pi; }
			while(cand[i] > pi){ cand[i] -= pi; }
			check(cand[i]);
		}
		sort(cand.begin(), cand.end());
		for(size_t i = 1; i < cand.size(); ++i){
			if(cand[i - 1] != cand[i]){
				P ret = check(0.5 * (cand[i - 1] + cand[i]));
				check(0.5 * pi - arg(ret));
			}
		}
		cout << tmin << '\n' << tmax << '\n';
	}
}
accuracy: 1
time_ms: 1840
memory_kb: 1552
final_rank: 1

code_snippet: #include<cstdio>
#include<complex>
#include<vector>
#include<cmath>
#include<iostream>
#include<string>
#include<utility>
#include<algorithm>

using namespace std;

typedef double Real;

typedef complex<Real> Point;
typedef complex<Real> Vector;
typedef pair<Point,Point> Segment;
typedef vector<Point> Polygon;

typedef pair<Real,int> P;
typedef pair<Real,Real> PR;

const Real eps=1e-9;
const Real PI=acos(-1.0);
const Real inf=1e9;

template<class T> bool eq(T a,T b){
	return abs(a-b)<eps;
}
template<class T> int sgn(T a){
	if(eq(a,0.0)) return 0;
	if(a>0) return 1;
	return -1;
}

Real arg(Vector v){
	return atan2(v.imag(),v.real());
}

Real getDis(Real a,Real x,Real y){
	return (a*x-y)/sqrt(a*a+1.0);
}

int xs[110],ys[110];
Point pts[110];
int N;

int NUM=0;

Real get(vector<P> vec){
	Real res=0;
	sort(vec.begin(),vec.end());
	int cnt=0;
	Real prev=-inf;
	for(int i=0;i<vec.size();i++){
		Real x=vec[i].first;
		int y=vec[i].second;
//		printf("(%f,%d)\n",x,y);
		if(cnt>0){
			res+=(x-prev);
		}
		prev=x;
		cnt+=y;
	}
//	printf("res=%f\n",res);
//	NUM++;
//	if(NUM==20) exit(0);
//	exit(0);
	return res;
}

Real calc(Real ang){
	vector<P> vec;
	if(eq(ang,PI/2)){
		for(int i=0;i<N;i++){
			vec.push_back(P(xs[i]-1,1));
			vec.push_back(P(xs[i]+1,-1));
		}
	}else{
		for(int i=0;i<N;i++){
		//	Real d=getDis(tan(PI/2-ang),xs[i],ys[i]);
			Real d=getDis(tan(-ang),xs[i],ys[i]);
			vec.push_back(P(d-1,1));
			vec.push_back(P(d+1,-1));
		}
	}
	Real res=get(vec);
	return res;
}

vector<Real> borders;

Real normalize(Real ang){
	if(sgn(ang)<=0){
		return -ang;
	}
	return abs(ang-PI);
}

Real normalize2(Real ang){
	while(ang<0) ang+=PI;
	while(ang>PI) ang-=PI;
	return ang;
}

void solve(Real lb,Real ub);

void solve(){
	for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){
		Vector v=pts[j]-pts[i];
		Real theta=arg(v);
		theta=normalize(theta);
		borders.push_back(theta);
		if(eq(abs(v),2.0)){
			if(sgn(theta-PI/2)>=0){
				borders.push_back(theta-PI/2);
			}else{
				borders.push_back(theta+PI/2);
			}
		}else{
			Real d=abs(v);
			Real phi=asin(2.0/d);
			borders.push_back(normalize2(theta+phi));
			borders.push_back(normalize2(theta-phi));
		}
	}
	sort(borders.begin(),borders.end());
	for(int i=0;i+1<borders.size();i++){
		solve(borders[i],borders[i+1]);
	}
}

PR mi,Ma;

void solve(Real lb,Real ub){
//	printf("[%f,%f]\n",lb,ub);
	Real x=calc(lb);
	mi=min(mi,PR(x,lb));
	Ma=max(Ma,PR(x,lb));
	x=calc(ub);
	mi=min(mi,PR(x,ub));
	Ma=max(Ma,PR(x,ub));
	if(eq(lb,ub)) return;
#if 0
	for(int stage=0;stage<100;stage++){
		Real dif=ub-lb;
		if(dif<eps) break;
		Real ang1=lb+(dif/3.0);
		Real ang2=lb+(dif*2/3.0);
		Real val1=calc(ang1);
		Real val2=calc(ang2);
		if(val1<val2){
			lb=ang1;
		}else{
			ub=ang2;
		}
	}
	Real val=calc(lb);
	Ma=max(Ma,PR(val,lb));
#endif
	vector<P> tmp;
	Real mid=(ub+lb)/2;
	for(int i=0;i<N;i++){
		Real L=sqrt(xs[i]*xs[i]+ys[i]*ys[i]);
		Real phi=atan2(ys[i],xs[i]);
		tmp.push_back(P(L*(sin(mid+phi)),i));
	}
	sort(tmp.begin(),tmp.end());
	Real coe_c=0,coe_s=0;
	Real c=0;
	for(int i=0;i<N;i++){
		if(i==0||sgn(tmp[i].first-tmp[i-1].first-2.0)>0){
			c+=1.0;
			int id=tmp[i].second;
			Real L=abs(pts[id]);
			Real phi=atan2(ys[id],xs[id]);
			coe_c-=L*sin(phi);
			coe_s-=L*cos(phi);
		}
		if(i==N-1||sgn(tmp[i+1].first-tmp[i].first-2.0)>0){
			c+=1.0;
			int id=tmp[i].second;
			Real L=abs(pts[id]);
			Real phi=atan2(ys[id],xs[id]);
			coe_c+=L*sin(phi);
			coe_s+=L*cos(phi);
		}
	}
	Real A=coe_c,B=coe_s;
	Real phi=-atan2(B,-A);
	phi=normalize2(phi);
//	printf("%f %f %f\n",lb,phi,ub);
	if(sgn(phi-lb)>=0&&sgn(ub-phi)>=0){
		Real x=calc(phi);
		Ma=max(Ma,PR(x,phi));
	}
}

void init(){
	borders.clear();
	mi=PR(inf,0);
	Ma=PR(-inf,0);
}

void input(){
	scanf("%d",&N);
	for(int i=0;i<N;i++){
		scanf("%d%d",xs+i,ys+i);
		pts[i]=Point(xs[i],ys[i]);
	}
}

int main(){
	int T=0;
	while(true){
		init();
		input();
		if(N==0) break;
//		if(T<60){
//			T++;
//			continue;
//		}
		solve();
		if(eq(mi.second,PI)) mi.second=0;
		if(eq(Ma.second,PI)) Ma.second=0;
		printf("%.12f\n",mi.second);
		printf("%.12f\n",Ma.second);
		T++;
//		if(T>=60&&T<70){
//			fprintf(stderr,"case %d\n",T);
//			fprintf(stderr,"borders.size()=%d\n",borders.size());
//		}
	}
	return 0;
}
accuracy: 1
time_ms: 3520
memory_kb: 1584
final_rank: 14

code_snippet: #include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
double x[110];
double y[110];
vector<double>v;
double PI=acos(-1.0);
double EPS=1e-12;
int n;
int bk[110];
double calc(double a){
	for(int i=0;i<n;i++)bk[i]=0;
	vector<pair<double,pair<int,int> > >ev;
	for(int i=0;i<n;i++){
		double ty=x[i]*sin(a)+y[i]*cos(a);
		ev.push_back(make_pair(ty-1,make_pair(1,i)));
		ev.push_back(make_pair(ty+1,make_pair(-1,i)));
	}
	std::sort(ev.begin(),ev.end());
	double ret=0;
	int now=0;
	for(int i=0;i<ev.size();i++){
		if(now)ret+=ev[i].first-ev[i-1].first;
		now+=ev[i].second.first;
	//	if(i<ev.size()-1&&ev[i+1].first-ev[i].first>EPS){
			if(ev[i].second.first==-1&&now==0){
				bk[ev[i].second.second]--;
			}
			if(ev[i].second.first==1&&now==1){
				bk[ev[i].second.second]++;
			}
		//}
	}
	//printf("%f: %f\n",a,ret);
	return ret;
}
double bf(double t){
	double ret=0;
	for(int i=0;i<n;i++){
		ret+=(x[i]*cos(t)-y[i]*sin(t))*bk[i];
	}
	return ret;
}
int main(){
	int a;
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++)scanf("%lf%lf",x+i,y+i);
		n=a;
		v.clear();
		v.push_back(0);
		v.push_back(PI);
		for(int i=0;i<a;i++)for(int j=i+1;j<a;j++){
			double th=atan2(y[j]-y[i],x[j]-x[i]);
			double th2;
			if(th>0){
				v.push_back(PI-th);
				th2=PI-th+PI/2;
			}else{
				v.push_back(-th);
				th2=-th+PI/2;
			}
			double d=sqrt((x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i]));
			d=max(d,2.0);
			double tt=acos(2.0/d);
			double t1=th2-tt;
			if(t1>PI)t1-=PI;
			if(t1<0)t1+=PI;
			v.push_back(t1);
			double t2=th2+tt;
			while(t2>PI)t2-=PI;
			v.push_back(t2);
		}
		std::sort(v.begin(),v.end());
		double tl=0;
		double tr=0;
		double vl=9999999;
		double vr=0;
		for(int i=0;i<v.size();i++){
			double val=calc(v[i]);
			if(vl>val){
				vl=val;tl=v[i];
			}
			if(vr<val){
				vr=val;tr=v[i];
			}
		}
		for(int i=0;i<v.size()-1;i++){
			if(v[i+1]-v[i]<EPS)continue;
	//		double p=(double)(rand()%100000)/100000;
			double M=(v[i]+v[i+1])/2;
			calc(M);
			double T=0;
			if(bf(v[i])<bf(v[i+1])){
				double L=v[i];
				double R=v[i+1];
				for(int j=0;j<100;j++){
					double m=(L+R)/2;
					double val=bf(m);
					if(val<0)L=m;
					else R=m;
				}
				T=L;
			}else{
				double L=v[i];
				double R=v[i+1];
				for(int j=0;j<100;j++){
					double m=(L+R)/2;
					double val=bf(m);
					if(val<0)R=m;
					else L=m;
				}
				T=L;
			}
	//		for(int j=0;j<a;j++)printf("%d ",bk[j]);
			
			double tmp=calc(T);
		//	printf("%f %f %f -> %f %f %f: %f\n",v[i],T,v[i+1],bf(v[i]),bf(T),bf(v[i+1]),tmp);
			if(vl>tmp){
				vl=tmp;tl=T;
			}
			if(vr<tmp){
				vr=tmp;tr=T;
			}
		}
	//	printf("%f %f\n",vl,vr);
		printf("%.15f\n%.15f\n",tl,tr);
	}
}
accuracy: 1
time_ms: 2510
memory_kb: 1348
final_rank: 2

code_snippet: #include <bits/stdc++.h>


using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;

const D PI = acos(-1);

int n;
P p[100];

D solve(D theta) {
  vector<D> xx;
  D st = sin(theta), ct = cos(theta);
  rep (i, n) xx.push_back(p[i].X * st + p[i].Y * ct);
  sort(xx.begin(), xx.end());
  D res = 2;
  rep (i, xx.size() - 1) res += min((D)2, xx[i + 1] - xx[i]);
  return res;
}

pair<D, D> solve2(D theta) {
  vector<pair<D, pair<D, D> > > xx;
  D st = sin(theta), ct = cos(theta);
  rep (i, n) xx.push_back(make_pair(p[i].X * st + p[i].Y * ct, make_pair(p[i].X, p[i].Y)));
  sort(xx.begin(), xx.end());
  D sx = 0, sy = 0;
  rep (i, xx.size() - 1) if (xx[i + 1].first - xx[i].first < 2) {
    sx += xx[i].second.first;
    sy += xx[i].second.second;
    sx -= xx[i + 1].second.first;
    sy -= xx[i + 1].second.second;
  }
  return make_pair(solve(atan2(sx, sy)), atan2(sx, sy));
}

int main() {
  while (true) {
    cin >> n;
    if (n == 0) break;
    rep (i, n) {
      D x, y;
      cin >> x >> y;
      p[i] = P(x, y);
    }
    vector<D> t;
    t.push_back(PI);
    t.push_back(0);
    rep (i, n) rep (j, i) {
      D t1 = -arg(p[i] - p[j]);
      D dt = asin((D)2 / abs(p[i] - p[j]));
      t.push_back(t1);
      t.push_back(t1 + dt);
      t.push_back(t1 - dt);
    }
    rep (i, t.size()) while (t[i] < 0) t[i] += PI;
    rep (i, t.size()) while (t[i] > PI) t[i] -= PI;
    sort(t.begin(), t.end());
    D ans = 1e9, theta = -1;
    rep (i, t.size()) {
      D s = solve(t[i]);
      if (s < ans) {
	ans = s;
	theta = t[i];
      }
    }
    rep (i, t.size() - 1) {
      pair<D, D> s = solve2((t[i] + t[i + 1]) / 2);
      if (s.first < ans) {
	ans = s.first;
	theta = s.second;
      }
    }
    while (theta < 0) theta += PI;
    while (theta > PI) theta -= PI;
    cout << fixed << setprecision(15) << theta << endl;
    ans = 0, theta = -1;
    rep (i, t.size()) {
      D s = solve(t[i]);
      if (s > ans) {
	ans = s;
	theta = t[i];
      }
    }
    rep (i, t.size() - 1) {
      pair<D, D> s = solve2((t[i] + t[i + 1]) / 2);
      if (s.first > ans) {
	ans = s.first;
	theta = s.second;
      }
    }
    while (theta < 0) theta += PI;
    while (theta > PI) theta -= PI;
    cout << fixed << setprecision(15) << theta << endl;
  }
}
accuracy: 1
time_ms: 4250
memory_kb: 1732
final_rank: 19

code_snippet: #include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const double EPS=1e-11;
const double INF=1e77;
const double PI=acos(-1);

struct point{
	double x,y;
	point():x(0),y(0){}
	point(double x,double y):x(x),y(y){}
	point operator+(const point &a)const{ return point(x+a.x,y+a.y); }
	point operator-(const point &a)const{ return point(x-a.x,y-a.y); }
};

point operator*(double c,const point &a){ return point(c*a.x,c*a.y); }

double abs(const point &a){ return sqrt(a.x*a.x+a.y*a.y); }

point rot(const point &a,double theta){ return point(a.x*cos(theta)-a.y*sin(theta),a.x*sin(theta)+a.y*cos(theta)); }

double arg(const point &a){
	double t=atan2(a.y,a.x);
	return t<0?t+2*PI:t;
}

struct line{
	point a,b;
	line(){}
	line(const point &a,const point &b):a(a),b(b){}
};

struct circle{
	point c;
	double r;
	circle():c(point(0,0)),r(0){}
	circle(const point &c,double r):c(c),r(r){}
};

int tangent(const circle &C1,const circle &C2,vector<line> &res){
	double d=abs(C1.c-C2.c);
	if(d<EPS) return 0;

	int c=0;
	// 内接線
	if(C1.r+C2.r<d-EPS){
		double t=acos((C1.r+C2.r)/d);
		res.push_back(line(C1.c+rot(C1.r/d*(C2.c-C1.c), t),C2.c+rot(C2.r/d*(C1.c-C2.c), t)));
		res.push_back(line(C1.c+rot(C1.r/d*(C2.c-C1.c),-t),C2.c+rot(C2.r/d*(C1.c-C2.c),-t)));
		c+=2;
	}
	else if(C1.r+C2.r<d+EPS){
		point p=C1.c+C1.r/d*(C2.c-C1.c);
		res.push_back(line(p,p+rot(C2.c-C1.c,PI/2)));
		c++;
	}

	// 外接線
	if(abs(C1.r-C2.r)<d-EPS){
		double t1=acos((C1.r-C2.r)/d),t2=PI-t1;
		res.push_back(line(C1.c+rot(C1.r/d*(C2.c-C1.c), t1),C2.c+rot(C2.r/d*(C1.c-C2.c),-t2)));
		res.push_back(line(C1.c+rot(C1.r/d*(C2.c-C1.c),-t1),C2.c+rot(C2.r/d*(C1.c-C2.c), t2)));
		c+=2;
	}
	else if(abs(C1.r-C2.r)<d+EPS){
		point p=C1.c+C1.r/d*(C2.c-C1.c);
		res.push_back(line(p,p+rot(C2.c-C1.c,PI/2)));
		c++;
	}

	return c;
}

int n;
circle C[100];

// 影たちの位置関係は θ=φ の状態から変わらないとして, dw/dθ = 0 を達成する θ を求める. ( w : 影の長さ )
double calc_peak(double phi){
	pair<double,int> pos[100];
	rep(i,n){
		pos[i]=make_pair(rot(C[i].c,phi).y,i);
	}
	sort(pos,pos+n);

	double a=0,b=0; // dw/dθ = 0 <=> a*cos(θ) + b*sin(θ) = 0
	int pre=0;
	for(int i=1;i<=n;i++){
		if(i==n || pos[i-1].first+1<pos[i].first-1){
			// 今見ている影の連結成分は長さは d*sin(t-θ)+2
			double d=abs(C[pos[i-1].second].c-C[pos[pre].second].c);
			double t=arg(C[pos[i-1].second].c-C[pos[pre].second].c);
			// d*cos(t-θ) = d*cos(t)*cos(θ) + d*sin(t)*sin(θ)
			a+=d*cos(t);
			b+=d*sin(t);

			pre=i;
		}
	}

	double res=PI-atan2(-a,b);
	if(res>PI) res-=PI;
	return res;
}

double calc_width(double phi){
	double pos[100];
	rep(j,n){
		pos[j]=rot(C[j].c,phi).y;
	}
	sort(pos,pos+n);

	double res=0,x=-INF;
	rep(i,n){
		x=max(x,pos[i]-1);
		res+=max(pos[i]+1-x,(double)0);
		x=max(x,pos[i]+1);
	}
	return res;
}

int main(){
	while(scanf("%d",&n),n){
		rep(i,n) scanf("%lf%lf",&C[i].c.x,&C[i].c.y), C[i].r=1;

		vector<line> L;
		rep(i,n) rep(j,i) tangent(C[i],C[j],L);

		vector<double> T; // 二円の共通接線の角度
		rep(i,L.size()){
			double phi=PI-arg(L[i].b-L[i].a);
			if(phi<0) phi+=PI;
			T.push_back(phi);
		}
		T.push_back(0);
		T.push_back(PI);
		sort(T.begin(),T.end());
		// unique
		rep(i,(int)T.size()-1) if(T[i+1]-T[i]<EPS) T.erase(T.begin()+i--);

		double mini=INF,phi_mini;
		double maxi= 0 ,phi_maxi;
		rep(i,T.size()){
			double w=calc_width(T[i]);
			if(w<mini) mini=w, phi_mini=T[i];
			if(w>maxi) maxi=w, phi_maxi=T[i];

			if(i+1<T.size()){
				double phi0=(T[i]+T[i+1])/2;
				double phi1=calc_peak(phi0);

				w=calc_width(phi1);
				if(w<mini) mini=w, phi_mini=phi1;
				if(w>maxi) maxi=w, phi_maxi=phi1;
			}
		}
		printf("%.15f\n",phi_mini);
		printf("%.15f\n",phi_maxi);
	}

	return 0;
}
accuracy: 1
time_ms: 1250
memory_kb: 2688
final_rank: 3