トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
CODE FESTIVAL 2015予選A B とても長い数列
■■■問題■■■
高橋君は長さNの数列 A={A1,A2, ・・・ ,AN} を用意しました。
高橋君は数列Aを元に「とても長い数列」を、
以下のような手順で作ろうとしています。
●まず長さ0の数列を用意し、これをSと呼ぶことにする。
●S、A1、S をこの順につなげた数列を新たなSとする。
●S、A2、S をこの順につなげた数列を新たなSとする。
● (中略)
●S、AN、S をこの順につなげた数列を新たなSとする。
●この時点でのSを「とても長い数列」とする。
例えば N=3,A1=1,A2=2,A3=3 なら、S は {} → {1} → {1,2,1} → {1,2,1,3,1,2,1} と変化し、
「とても長い数列」は {1,2,1,3,1,2,1} となります。
高橋君はこの手順によって作られる「とても長い数列」に含まれる数の和を知りたがっています。
これを高橋君の代わりに計算するプログラムを作成してください。
■■■入力■■■
N
A1 A2 ... AN
●1行目には、整数 N(1 <= N <= 30) が与えられる。
●2行目には、N個の整数が空白区切りで与えられる。
このうち i(1 <= i <= N) 番目には、整数 Ai(0 <= Ai <= 100) が与えられる。
●「とても長い数列」に含まれる数の和は 10の9乗以下となることが保証されている。
■■■出力■■■
「とても長い数列」に含まれる数の和を1行に出力せよ。出力の末尾に改行を入れること。
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "Input2";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3");
WillReturn.Add("1 2 3");
//11
//この入力例は問題文中の例と同じです。
//「とても長い数列」は {1,2,1,3,1,2,1} となり、
//1+2+1+3+1+2+1=11 であるため11を出力します。
}
else if (InputPattern == "Input2") {
WillReturn.Add("8");
WillReturn.Add("0 1 3 6 12 25 50 100");
//652
}
else if (InputPattern == "Input3") {
WillReturn.Add("30");
WillReturn.Add("1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0");
//536870912
//「とても長い数列」はとても長くなることがあるので注意してください
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] AArr = InputList[1].Split(' ').Select(X => int.Parse(X)).ToArray();
int N = AArr.Length;
int SumVal = 0;
for (int I = 0; I <= AArr.GetUpperBound(0); I++) {
SumVal += AArr[I] * (int)Math.Pow(2, N - I - 1);
}
Console.WriteLine(SumVal);
}
}
解説
数列を構成する整数が順に、1 2 3であれば
1+
1+2+1+
1+2+1+3+1+2+1
が解となります。
これは
1*(2の3乗-1)
+2*(2の2乗-1)
+3*(2の1乗-1)
であることを使って計算してます。