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

ARC012-C 五目並べチェッカー


問題へのリンク


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("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("....x......o.......");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add(".......o....o......");
            WillReturn.Add("...................");
            WillReturn.Add("........x..........");
            WillReturn.Add("..............o....");
            WillReturn.Add("...................");
            WillReturn.Add(".......x...........");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            //YES
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("....x......o.......");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add(".......o....o......");
            WillReturn.Add("...................");
            WillReturn.Add("........x..........");
            WillReturn.Add("..............o....");
            WillReturn.Add("...................");
            WillReturn.Add(".......x...........");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add(".........o.........");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            //NO
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("........ooooo......");
            WillReturn.Add(".........xxxx......");
            WillReturn.Add("........x..........");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            //NO
        }
        else if (InputPattern == "Input4") {
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("........ooooo......");
            WillReturn.Add(".........xxxx......");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            //YES
        }
        else if (InputPattern == "Input5") {
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add(".........x.........");
            WillReturn.Add("......oooooo.......");
            WillReturn.Add("........xxxx.......");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            //YES
        }
        else if (InputPattern == "Input6") {
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("........x..........");
            WillReturn.Add("........x....x.....");
            WillReturn.Add("...........x.......");
            WillReturn.Add("...oooooooooo......");
            WillReturn.Add("...................");
            WillReturn.Add("......x......x.....");
            WillReturn.Add("....x......x.......");
            WillReturn.Add(".........x.........");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            //NO
        }
        else if (InputPattern == "Input7") {
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            WillReturn.Add("...................");
            //YES
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    const int UB = 19 - 1;

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

        char[,] BanArr = CreateBanArr(InputList);

        //PrintBan(BanArr);

        // チェック01 黒勝ち、かつ、白黒勝ちならNG
        if (IsCorrect_01(BanArr) == false) {
            Console.WriteLine("NO");
            return;
        }

        // チェック02 石の数のチェック
        if (IsCorrect_02(BanArr) == false) {
            Console.WriteLine("NO");
            return;
        }

        // チェック3 黒勝ちで、どの黒石を除外しても、黒勝ちならNG
        if (IsCorrect_03(BanArr) == false) {
            Console.WriteLine("NO");
            return;
        }

        // チェック4 黒勝ちで、どの黒石を除外しても、黒勝ちならNG
        if (IsCorrect_04(BanArr) == false) {
            Console.WriteLine("NO");
            return;
        }
        Console.WriteLine("YES");
    }

    // チェック01 黒勝ち、かつ、白黒勝ちならNG
    static bool IsCorrect_01(char[,] pBanArr)
    {
        bool IsWinBlack = IsWin(pBanArr, 'o');
        bool IsWinWhite = IsWin(pBanArr, 'x');

        if (IsWinBlack && IsWinWhite) return false;
        return true;
    }

    // チェック02 石の数のチェック
    static bool IsCorrect_02(char[,] pBanArr)
    {
        int BlackCnt = pBanArr.Cast<char>().Count(pX => pX == 'o');
        int WhileCnt = pBanArr.Cast<char>().Count(pX => pX == 'x');

        // 黒勝ちの場合
        if (IsWin(pBanArr, 'o')) {
            return BlackCnt == WhileCnt + 1;
        }

        // 白勝ちの場合
        if (IsWin(pBanArr, 'x')) {
            return BlackCnt == WhileCnt;
        }

        if (BlackCnt == WhileCnt) return true;
        if (BlackCnt == WhileCnt + 1) return true;

        return false;
    }

    // チェック3 黒勝ちで、どの黒石を除外しても、黒勝ちならNG
    static bool IsCorrect_03(char[,] pBanArr)
    {
        if (IsWin(pBanArr, 'o') == false) {
            return true;
        }
        for (int X = 0; X <= UB; X++) {
            for (int Y = 0; Y <= UB; Y++) {
                if (pBanArr[X, Y] != 'o') continue;

                char[,] CopiedBanArr = (char[,])pBanArr.Clone();
                CopiedBanArr[X, Y] = '.';

                if (IsWin(CopiedBanArr, 'o') == false) {
                    return true;
                }
            }
        }
        return false;
    }

    // チェック4 白勝ちで、どの白石を除外しても、白勝ちならNG
    static bool IsCorrect_04(char[,] pBanArr)
    {
        if (IsWin(pBanArr, 'x') == false) {
            return true;
        }
        for (int X = 0; X <= UB; X++) {
            for (int Y = 0; Y <= UB; Y++) {
                if (pBanArr[X, Y] != 'x') continue;

                char[,] CopiedBanArr = (char[,])pBanArr.Clone();
                CopiedBanArr[X, Y] = '.';

                if (IsWin(CopiedBanArr, 'x') == false) {
                    return true;
                }
            }
        }
        return false;
    }

    // 引数とした色の勝ちの盤面かを判定する
    static bool IsWin(char[,] pBanArr, char pColor)
    {
        for (int X = 0; X <= UB; X++) {
            for (int Y = 0; Y <= UB; Y++) {
                if (pBanArr[X, Y] != pColor) continue;

                // 右方向
                if (HasFiveSeq(pBanArr, X, Y, 1, 0)) return true;

                // 下方向
                if (HasFiveSeq(pBanArr, X, Y, 0, 1)) return true;

                // 右下方向
                if (HasFiveSeq(pBanArr, X, Y, 1, 1)) return true;

                // 左下方向
                if (HasFiveSeq(pBanArr, X, Y, -1, 1)) return true;
            }
        }
        return false;
    }

    // 指定した座標から、ベクトルの方向に、同じ石が、5つ連続しているかを判定
    static bool HasFiveSeq(char[,] pBanArr, int pStaX, int pStaY, int pVectorX, int pVectorY)
    {
        char TargetColor = pBanArr[pStaX, pStaY];

        int CurrX = pStaX;
        int CurrY = pStaY;

        for (int I = 1; I <= 5; I++) {
            if (CurrX < 0 || UB < CurrX) return false;
            if (CurrY < 0 || UB < CurrY) return false;
            if (pBanArr[CurrX, CurrY] != TargetColor) return false;

            CurrX += pVectorX;
            CurrY += pVectorY;
        }
        return true;
    }

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


解説

必要条件を順次チェックしてます。