AtCoderのABC    次のABCの問題へ    前のABCの問題へ

ABC197-B Visibility


問題へのリンク


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

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

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

        int[] wkArr = InputList[0].Split(' ').Select(pX => int.Parse(pX)).ToArray();
        UB_X = wkArr[1] - 1;
        UB_Y = wkArr[0] - 1;
        mX = wkArr[3] - 1;
        mY = wkArr[2] - 1;

        mBanArr = CreateBanArr(InputList.Skip(1).ToList());

        var AnswerSet = new HashSet<long>();
        AnswerSet.UnionWith(DeriveCanMovePosSet(0, -1));
        AnswerSet.UnionWith(DeriveCanMovePosSet(0, +1));
        AnswerSet.UnionWith(DeriveCanMovePosSet(-1, 0));
        AnswerSet.UnionWith(DeriveCanMovePosSet(+1, 0));
        Console.WriteLine(AnswerSet.Count);
    }

    // 変位ベクトルを引数として、移動可能な座標のHash値のSetを返す
    static HashSet<long> DeriveCanMovePosSet(int pHeniX, int pHeniY)
    {
        var WillReturn = new HashSet<long>();
        int CurrX = mX;
        int CurrY = mY;

        while (true) {
            if (CurrX < 0 || UB_X < CurrX) break;
            if (CurrY < 0 || UB_Y < CurrY) break;

            if (mBanArr[CurrX, CurrY] == '#') break;

            WillReturn.Add(CurrX * 1000 + CurrY);

            CurrX += pHeniX;
            CurrY += pHeniY;
        }
        return WillReturn;
    }

    // stringのListをcharの2次元配列に設定する
    static char[,] CreateBanArr(List<string> pStringList)
    {
        if (pStringList.Count == 0) {
            return new char[0, 0];
        }
        int UB_X = pStringList[0].Length - 1;
        int UB_Y = pStringList.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] = pStringList[Y][X];
            }
        }
        return WillReturn;
    }

    // 2次元配列のデバッグ出力
    static void PrintBan(char[,] pBanArr)
    {
        for (int Y = 0; Y <= pBanArr.GetUpperBound(1); Y++) {
            for (int X = 0; X <= pBanArr.GetUpperBound(0); X++) {
                Console.Write(pBanArr[X, Y]);
            }
            Console.WriteLine();
        }
    }
}


解説

4通りの移動を変位ベクトルとして、メソッドの引数にして、
ソースを共通化してます。