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: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;




class Program 
{
    const int MOD = 1000000007;
    const long INF = 1 << 61;



    static void Main(string[] args) 
    {
        
        Solve();
    }



    static void Solve() 
    {
        Scaner cin = new Scaner();
        write cout = new write();
        Math2 mmath = new Math2();
        //ここから
        var o = cin.IntM;
        double a = o[0];
        double b = o[1];
        double x = o[2];

        double c = 2*x/a*a-b;
        double d = 2*a/b*x;
        if (2*x>a*a*b)
        {
            double ans = Math.Atan((b-c)/a);
            cout.wri(ans*180/Math.PI);
        }
        else
        {
            double ans = Math.Atan(d / b);
            cout.wri(ans * 180 / Math.PI);

        }
    }


}






//b-aで降順

    //priority queue
class PriorityQueue<T> 
{
    private readonly List<T> heap;
    private readonly Comparison<T> compare;
    private int size;
    public PriorityQueue() : this(Comparer<T>.Default) {} 
    public PriorityQueue(IComparer<T> comparer) : this(16, comparer.Compare) { }
    public PriorityQueue(Comparison<T> comparison) : this(16, comparison) { }
    public PriorityQueue(int capacity, Comparison<T> comparison)
    {
        this.heap = new List<T>(capacity);
        this.compare = comparison;
    }
    public void Enqueue(T item)
    {
        this.heap.Add(item);
        var i = size++;
        while (i > 0)
        {
            var p = (i - 1) >> 1;
            if (compare(this.heap[p], item) <= 0)
                break;
            this.heap[i] = heap[p];
            i = p;
        }
        this.heap[i] = item;

    }
    public T Dequeue()
    {
        var ret = this.heap[0];
        var x = this.heap[--size];
        var i = 0;
        while ((i << 1) + 1 < size)
        {
            var a = (i << 1) + 1;
            var b = (i << 1) + 2;
            if (b < size && compare(heap[b], heap[a]) < 0) a = b;
            if (compare(heap[a], x) >= 0)
                break;
            heap[i] = heap[a];
            i = a;
        }
        heap[i] = x;
        heap.RemoveAt(size);
        return ret;
    }
    public T Peek() { return heap[0]; }
    public int Count { get { return size; } }
    public bool Any() { return size > 0; }
}


 public class Math2
{
    public long[] Fact;  //Nまでの階乗
    public long[] invFact;  //階乗の逆元

    //Nまでの階乗をセットしておく
    public void FactoricalModSet(long N,long MOD=1000000007)
    {
        Fact = new long[N + 1];
        invFact = new long[N + 1];

        Fact[0] = 1;
        for(long i = 1; i <= N; ++i)
        {
            Fact[i] = Fact[i - 1] * i%MOD;
        }
        invFact[N] = pow(Fact[N], MOD - 2);

        for (long i = N; i > 0; --i)
        {
            invFact[i - 1] = invFact[i] * i%MOD;
        }

    }

    //nCr 引数:n r (mod)
    public long nCr(long n,long r,long MOD=1000000007)
    {
        return (Fact[n] * invFact[r] % MOD * invFact[n-r]%MOD);
    }

    //階乗(O(logN)) 引数:底x n乗　(MOD)
    public long pow(long x,long n,long MOD = 1000000007)
    {
        long res = 1;
        while (n > 0)
        {
            if ((n & 1) != 0) res = res * x % MOD;
            x = x * x % MOD;
            n >>= 1;
        }
        return res;
    }

    //最大公約数 引数:整数x,y
    public long GCD(long x, long y)
    {
        while (y != 0)
        {
            var r = x % y;
            x = y;
            y = r;
        }
        return x;
    }

    //最小公倍数 引数:整数x,y
    public long LCM(long x, long y)
    {
        return x * y / GCD(x, y);
    }

    //素因数分解 引数:整数N
    public Dictionary<long,int > PrimeFactorization(long N)
    {
        var ret = new Dictionary<long,int>();

        for(long i = 2; i*i <= N; ++i)
        {
            int cnt = 0;
            while (N % i == 0)
            {
                cnt++;
                N /= i;
            }
            if (cnt != 0) ret[i] = cnt;

        }
        if (N >= 2)ret[N]=1;

        return ret;

    }
    public List<long> PrimeFactorization2(long N)
    {
        var ret = new List<long>();

        for (long i = 1; i * i <= N; ++i)
        {

            if (N % i == 0)
            {
                ret.Add(i);
                ret.Add(N / i);
            }

        }

        return ret;

    }

}


namespace CompLib.Algorithms
{

    #region BinarySearch
    public static partial class Algorithm
    {
        static int binarySearch<T>(IList<T> a, T v, IComparer<T> cmp, bool islb)
        {
            var l = 0;
            var r = a.Count - 1;
            while (l <= r)
            {
                var m = (l + r) / 2;
                var res = cmp.Compare(a[m], v);
                if (res < 0 || (res == 0 && !islb)) l = m + 1;
                else r = m - 1;
            }
            return l;
        }

        /// <summary>
        /// 与えられた比較関数に従って，<paramref name="a"/> の要素のうち，<paramref name="v"/> 以上の要素であるような最小のインデックスを取得します．
        /// </summary>
        /// <typeparam name="T"><see cref="IList{T}"/> の要素の型を指定します．</typeparam>
        /// <param name="a">対象となるコレクション</param>
        /// <param name="v">対象となる要素</param>
        /// <param name="f"></param>
        /// <returns><paramref name="v"/> 以上の要素であるような最小の o-indexed でのインデックス．</returns>
        /// <remarks> <paramref name="a"/> は比較関数に対して昇順であることを仮定しています．この関数は O(log N) で実行されます．</remarks>
        public static int LowerBound<T>(this IList<T> a, T v, Comparison<T> f) { return binarySearch(a, v, Comparer<T>.Create(f), true); }

        /// <summary>
        ///　デフォルトの比較関数に従って，<paramref name="a"/> の要素のうち，<paramref name="v"/> 以上の要素であるような最小のインデックスを取得します．
        /// </summary>
        /// <typeparam name="T"><see cref="IList{T}"/> の要素の型を指定します．</typeparam>
        /// <param name="a">対象となるコレクション</param>
        /// <param name="v">対象となる要素</param>
        /// <param name="f"></param>
        /// <returns><paramref name="v"/> 以上の要素であるような最小の o-indexed でのインデックス．</returns>
        /// <remarks> <paramref name="a"/> は比較関数に対して昇順であることを仮定しています．この関数は O(log N) で実行されます．</remarks>
        public static int LowerBound<T>(this IList<T> a, T v) { return binarySearch(a, v, Comparer<T>.Default, true); }

        /// <summary>
        /// 与えられた比較関数に従って，<paramref name="a"/> の要素のうち，<paramref name="v"/> 以上の要素であるような最小のインデックスを取得します．
        /// </summary>
        /// <typeparam name="T"><see cref="IList{T}"/> の要素の型を指定します．</typeparam>
        /// <param name="a">対象となるコレクション</param>
        /// <param name="v">対象となる要素</param>
        /// <param name="f"></param>
        /// <returns><paramref name="v"/> 以上の要素であるような最小の o-indexed でのインデックス．</returns>
        /// <remarks> <paramref name="a"/> は比較関数に対して昇順であることを仮定しています．この関数は O(log N) で実行されます．</remarks>
        public static int UpperBound<T>(this IList<T> a, T v, Comparison<T> cmp) { return binarySearch(a, v, Comparer<T>.Create(cmp), false); }

        /// <summary>
        ///　デフォルトの比較関数に従って，<paramref name="a"/> の要素のうち，<paramref name="v"/> より真に大きい要素が現れる最小のインデックスを取得します．
        /// </summary>
        /// <typeparam name="T"><see cref="IList{T}"/> の要素の型を指定します．</typeparam>
        /// <param name="a">対象となるコレクション</param>
        /// <param name="v">対象となる要素</param>
        /// <param name="f"></param>
        /// <returns><paramref name="v"/> 以上の要素であるような最小の o-indexed でのインデックス．</returns>
        /// <remarks> <paramref name="a"/> は比較関数に対して昇順であることを仮定しています．この関数は O(log N) で実行されます．</remarks>
        public static int UpperBound<T>(this IList<T> a, T v) { return binarySearch(a, v, Comparer<T>.Default, false); }

    }
    #endregion
}







class Scaner
{
    public string Str => Console.ReadLine();

    public string[] StrM => Str.Split(' ');

    public long[] LongM => StrM.Select(long.Parse).ToArray();
    public int[] IntM => StrM.Select(int.Parse).ToArray();
    public char[] CharM => Str.ToArray();
    public long Long1 => LongM[0];
    public int Int1 => IntM[0];
    
}



class write
{
    public  void wri<T>(T x)
    {
        Console.WriteLine(x);
    }
}