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

ARC038-B マス目と駒


問題へのリンク


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 3");
            WillReturn.Add(".#.");
            WillReturn.Add("...");
            //First
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("4 4");
            WillReturn.Add("....");
            WillReturn.Add("...#");
            WillReturn.Add("....");
            WillReturn.Add(".#..");
            //Second
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("11 44");
            WillReturn.Add("............................................");
            WillReturn.Add("............................................");
            WillReturn.Add("............................................");
            WillReturn.Add(".....#.....#####....####.....####....####...");
            WillReturn.Add("....#.#....#....#..#....#...#....#..#....#..");
            WillReturn.Add("....#.#....#....#..#.............#..#....#..");
            WillReturn.Add("...#####...#####...#..........###....####...");
            WillReturn.Add("...#...#...#....#..#.............#..#....#..");
            WillReturn.Add("..#.....#..#....#..#....#...#....#..#....#..");
            WillReturn.Add("..#.....#..#....#...####.....####....####...");
            WillReturn.Add("............................................");
            //Second
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static char[,] mBanArr;
    static int UB_X;
    static int UB_Y;

    // 手番を持った時に勝ちか? [X座標,Y座標]
    static bool?[,] mDPArr;

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

        mBanArr = CreateBanArr(InputList.Skip(1));
        UB_X = mBanArr.GetUpperBound(0);
        UB_Y = mBanArr.GetUpperBound(1);

        mDPArr = new bool?[UB_X + 1, UB_Y + 1];

        // メモ化再帰で解く
        DFS(0, 0);

        //for (int Y = 0; Y <= UB_Y; Y++) {
        //    for (int X = 0; X <= UB_X; X++) {
        //        Console.WriteLine("mDPArr[{0},{1}]={2}", X, Y, mDPArr[X, Y]);
        //    }
        //}

        Console.WriteLine(mDPArr[0, 0].Value ? "First" : "Second");
    }

    static bool DFS(int pCurrX, int pCurrY)
    {
        if (mDPArr[pCurrX, pCurrY].HasValue) {
            return mDPArr[pCurrX, pCurrY].Value;
        }

        var SeniList = new List<bool>();

        Action<int, int> AddAct = (pNewX, pNewY) =>
        {
            if (pNewX < 0 || UB_X < pNewX) return;
            if (pNewY < 0 || UB_Y < pNewY) return;

            if (mBanArr[pNewX, pNewY] == '#') return;

            SeniList.Add(DFS(pNewX, pNewY));
        };
        AddAct(pCurrX, pCurrY + 1);
        AddAct(pCurrX + 1, pCurrY);
        AddAct(pCurrX + 1, pCurrY + 1);

        // 相手を負けにできる手が少なくとも1つあれば、勝ち
        if (SeniList.Contains(false)) {
            mDPArr[pCurrX, pCurrY] = true;
            return true;
        }
        // 相手を負けにできる手がない場合は、負け
        mDPArr[pCurrX, pCurrY] = false;
        return false;
    }

    ////////////////////////////////////////////////////////////////
    // IEnumerable<string>をcharの2次元配列に設定する
    ////////////////////////////////////////////////////////////////
    static char[,] CreateBanArr(IEnumerable<string> pStrEnum)
    {
        var StrList = pStrEnum.ToList();
        if (StrList.Count == 0) {
            return new char[0, 0];
        }
        int UB_X = StrList[0].Length - 1;
        int UB_Y = StrList.Count - 1;

        char[,] WillReturn = new char[UB_X + 1, UB_Y + 1];

        for (int Y = 0; Y <= UB_Y; Y++) {
            for (int X = 0; X <= UB_X; X++) {
                WillReturn[X, Y] = StrList[Y][X];
            }
        }
        return WillReturn;
    }
}


解説

メモ化再帰で解いてます。


類題

ABC195-E Lucky 7 Battle