AtCoderのARC    次のARCの問題へ    前のARCの問題へ

ARC117-B ARC Wrecker


問題へのリンク


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("2");
            WillReturn.Add("1 2");
            //4
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("6");
            WillReturn.Add("5 3 4 1 5 2");
            //32
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("7");
            WillReturn.Add("314 159 265 358 979 323 846");
            //492018656
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    const long Hou = 1000000007;

    static void Main()
    {
        List<string> InputList = GetInputList();

        long[] AArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
        AArr = AArr.Distinct().OrderBy(pX => pX).ToArray();

        // 階差数列
        var KaisaList = new List<long>();
        KaisaList.Add(AArr[0]);
        for (int I = 1; I <= AArr.GetUpperBound(0); I++) {
            KaisaList.Add(AArr[I] - AArr[I - 1]);
        }

        long Answer = 1;
        foreach (long EachKaisa in KaisaList) {
            Answer *= (EachKaisa + 1);
            Answer %= Hou;
        }
        Console.WriteLine(Answer);
    }
}


解説

前提として、
ソートしておよび重複を消しても問題ないです。

必ず、何もない状態に遷移可能なので、
何もない状態から、戻せるビルの形を考えます。

  □
  □
 □□
 □□
□□□

上記のビルの形だったとして、
大砲によって消える個所ごとにアルファベットを振ると下記になります。

  C
  C
 BB
 BB
AAA

復元可能なビルの形の、場合の数は、
Aは、選ばないか1行選ぶで2通り
Bは、選ばないか1行か2行選ぶで3通り
Cは、選ばないか1行か2行選ぶで3通り
なので、積の法則により、2*3*3 = 18 通りになります。

そして、A、B、Cの選択可能行数は、ソートした数列の、階差数列になります。