東大卒のお金やりくり奮闘記~株、家計、趣味、経済~

東大卒でメーカー勤務の私がセミリタイアするために投資などを頑張っていこうという趣旨で始めたブログです。既婚男性です。株、家計、趣味、経済の話をメインにゆるゆる話します。

NOMURAプログラミングコンテストで書いたコード

using System;
using System.Numerics;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace debug
{
    class main
    {
        static void Main(string args)
        {
            //問題クラスを展開
            ProgramC a = new ProgramC();
            a.main();//実行する

        }

    }

    class ProgramA
    {
        public void main()
        {
            //入力
            string s = Console.ReadLine().Split(' ');
            int a = int.Parse(s[0]);
            int b = int.Parse(s[1]);
            int c = int.Parse(s[2]);
            int d = int.Parse(s[3]);
            int e = int.Parse(s[4]);

            //時間に換算して起きてる時間からk時間を除く
            Console.WriteLine(d + c * 60 - b - a * 60 - e);

        }
    }

    class ProgramB
    {
        public void main()
        {
            //入力
            string s = Console.ReadLine();

            //?はD、それ以外は普通に出す
            for(int i = 0;i < s.Length;i++)
            {
                if(s[i] == '?')
                {
                    Console.Write('D');
                }
                else
                {
                    Console.Write(s[i]);
                }
            }
            

        }
    }

    class ProgramC
    {
        public void main()
        {

            int n = int.Parse(Console.ReadLine());
            string a = Console.ReadLine().Split(' ');

            //n=0のときは例外処理
            if(n == 0)
            {
                if (a[0] == "1")
                    Console.WriteLine("1");
                else
                    Console.WriteLine("-1");
                return;
            }
            //0のときは0以外はダメ
            if(a[0] != "0")
            {
                Console.WriteLine("-1");
                return;
            }
            long num = new long[n + 1];
            long[] leave = new long[n + 1];
            num[0] = 1;
            leave[n] = long.Parse(a[n]);
            //深さiを含む後ろの根の数を数えておく
            for (int i = n -1i >= 0 ;i--)
                leave[i] = leave[i + 1] + long.Parse(a[i]);
            //前から根の数を決める(ただし、最大は後ろに考えるべき根の数に限られる)
            for(int i = 1;i <= n;i++)
            {
                num[i] = Math.Min(2 * (num[i - 1] - long.Parse(a[i - 1])), leave[i]);
                //あり得る数が葉になる数より大きければあり得ない(n-1まで)
                if(i < n && num[i] <= long.Parse(a[i]))
                {
                    Console.WriteLine("-1");
                    return;
                }
                //最後は頭からの条件で満たさないならアウト
                if (i == n && num[i] < long.Parse(a[i]))
                {
                    Console.WriteLine("-1");
                    return;
                }
            }
            
            //答え出力
            long ans = 0;
            for(int i = 0i <= n;i++)
                ans += num[i];

            Console.WriteLine(ans);
        }
    }
}