Problem:
Score : 400 points

Problem Statement

Takahashi has a water bottle with the shape of a rectangular prism whose base is a square of side a~\mathrm{cm} and whose height is b~\mathrm{cm}. (The thickness of the bottle can be ignored.)

We will pour x~\mathrm{cm}^3 of water into the bottle, and gradually tilt the bottle around one of the sides of the base.

When will the water be spilled? More formally, find the maximum angle in which we can tilt the bottle without spilling any water.

Constraints

All values in input are integers.

1 \leq a \leq 100

1 \leq b \leq 100

1 \leq x \leq a^2b

Input

Input is given from Standard Input in the following format:

a b x

Output

Print the maximum angle in which we can tilt the bottle without spilling any water, in degrees.
Your output will be judged as correct when the absolute or relative error from the judge's output is at most 10^{-6}.

Sample Input 1

2 2 4

Sample Output 1

45.0000000000

This bottle has a cubic shape, and it is half-full. The water gets spilled when we tilt the bottle more than 45 degrees.

Sample Input 2

12 21 10

Sample Output 2

89.7834636934

This bottle is almost empty. When the water gets spilled, the bottle is nearly horizontal.

Sample Input 3

3 1 8

Sample Output 3

4.2363947991

This bottle is almost full. When the water gets spilled, the bottle is still nearly vertical.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using Number = System.Int32;

namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var a = ri;
			var b = ri;
			var x = (1.0 * ri) / a;
			//a * b の長方形
			var ans = 0.0;
			if (x * 2 < a * b) {
				var y = x * 2 / b;
				Debug.WriteLine($"{a} {b} {x} {y}");
				var th = Math.Atan2(y, b);
				Debug.WriteLine(y);
				Console.WriteLine(90 - (th * 180 / Math.PI));
			}
			else {
				x = a * b - x;
				var y = x * 2 / a;
				var th = Math.Atan2(y, a);
				Debug.WriteLine(y);
				Console.WriteLine(th * 180 / Math.PI);
			}
		}
		const long INF = 1L << 60;
		static int[] dx = { -1, 0, 1, 0 };
		static int[] dy = { 0, 1, 0, -1 };
		int ri { get { return sc.Integer(); } }
		long rl { get { return sc.Long(); } }
		double rd { get { return sc.Double(); } }
		string rs { get { return sc.Scan(); } }
		public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

		static T[] Enumerate<T>(int n, Func<int, T> f) {
			var a = new T[n];
			for (int i = 0; i < a.Length; ++i) a[i] = f(i);
			return a;
		}
		static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
	}
}

#region main
static class Ex {
	static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
	static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
		return string.Join(st, ie);
	}
	static public void Main() {
		Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = true });
		var solver = new Program.Solver();
		/* 
		var t = new System.Threading.Thread(solver.Solve, 50000000);
		t.Start();
		t.Join();
		//*/
		solver.Solve();
		Console.Out.Flush();
	}
}
#endregion
#region Ex
namespace Program.IO {
	using System.IO;
	using System.Text;
	using System.Globalization;

	public class Printer : StreamWriter {
		public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
		public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	}

	public class StreamScanner {
		public StreamScanner(Stream stream) { str = stream; }

		public readonly Stream str;
		private readonly byte[] buf = new byte[1024];
		private int len, ptr;
		public bool isEof = false;
		public bool IsEndOfStream { get { return isEof; } }

		private byte read() {
			if (isEof) return 0;
			if (ptr >= len) {
				ptr = 0;
				if ((len = str.Read(buf, 0, 1024)) <= 0) {
					isEof = true;
					return 0;
				}
			}
			return buf[ptr++];
		}

		public char Char() {
			byte b = 0;
			do b = read(); while ((b < 33 || 126 < b) && !isEof);
			return (char)b;
		}
		public string Scan() {
			var sb = new StringBuilder();
			for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
			return sb.ToString();
		}
		public string ScanLine() {
			var sb = new StringBuilder();
			for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
			return sb.ToString();
		}
		public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
		public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
		public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
	}
}

#endregion

#region ModInt
/// <summary>
/// [0,<see cref="Mod"/>) までの値を取るような数
/// </summary>
public struct ModInt {
	/// <summary>
	/// 剰余を取る値．
	/// </summary>
	public const long Mod = (int)1e9 + 7;

	/// <summary>
	/// 実際の数値．
	/// </summary>
	public long num;
	/// <summary>
	/// 値が <paramref name="n"/> であるようなインスタンスを構築します．
	/// </summary>
	/// <param name="n">インスタンスが持つ値</param>
	/// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
	public ModInt(long n) { num = n; }
	/// <summary>
	/// このインスタンスの数値を文字列に変換します．
	/// </summary>
	/// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
	public override string ToString() { return num.ToString(); }
	public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
	public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
	public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
	public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

	/// <summary>
	/// 与えられた 2 つの数値からべき剰余を計算します．
	/// </summary>
	/// <param name="v">べき乗の底</param>
	/// <param name="k">べき指数</param>
	/// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
	public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

	/// <summary>
	/// 与えられた 2 つの数値からべき剰余を計算します．
	/// </summary>
	/// <param name="v">べき乗の底</param>
	/// <param name="k">べき指数</param>
	/// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
	public static ModInt Pow(long v, long k) {
		long ret = 1;
		for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
			if ((k & 1) == 1) ret = ret * v % Mod;
		return new ModInt(ret);
	}
	/// <summary>
	/// 与えられた数の逆元を計算します．
	/// </summary>
	/// <param name="v">逆元を取る対象となる数</param>
	/// <returns>逆元となるような値</returns>
	/// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
	public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
}
#endregion
#region Binomial Coefficient
public class BinomialCoefficient {
	public ModInt[] fact, ifact;
	public BinomialCoefficient(int n) {
		fact = new ModInt[n + 1];
		ifact = new ModInt[n + 1];
		fact[0] = 1;
		for (int i = 1; i <= n; i++)
			fact[i] = fact[i - 1] * i;
		ifact[n] = ModInt.Inverse(fact[n]);
		for (int i = n - 1; i >= 0; i--)
			ifact[i] = ifact[i + 1] * (i + 1);
		ifact[0] = ifact[1];
	}
	public ModInt this[int n, int r] {
		get {
			if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
			return fact[n] * ifact[n - r] * ifact[r];
		}
	}
	public ModInt RepeatedCombination(int n, int k) {
		if (k == 0) return 1;
		return this[n + k - 1, k];
	}
}
#endregion