競プロをしながら、節約と株式投資でセミリタイアを目指す東大卒のブログ

東大卒でメーカー勤務の私がセミリタイアするために投資や競プロを頑張っていこうという趣旨で始めたブログです。独身男性です。お金の大切さや今後の生き方も併せて伝えられたらと思います。

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);
        }
    }
}