AtCoderのAGC    次のAGCの問題へ

AGC002-B Box and Ball


問題へのリンク


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

    struct XYInfoDef
    {
        internal int X;
        internal int Y;
    }

    class ExInfoDef
    {
        internal int BallCnt;
        internal bool HasRed;
    }

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

        int[] wkArr = { };
        Action<string> SplitAct = pStr =>
            wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();

        SplitAct(InputList[0]);
        int N = wkArr[0];

        var XYInfoList = new List<XYInfoDef>();
        foreach (string EachStr in InputList.Skip(1)) {
            XYInfoDef WillAdd;
            SplitAct(EachStr);
            WillAdd.X = wkArr[0];
            WillAdd.Y = wkArr[1];
            XYInfoList.Add(WillAdd);
        }

        var ExDict = new SortedDictionary<long, ExInfoDef>();
        for (int I = 1; I <= N; I++) {
            ExDict[I] = new ExInfoDef();
            ExDict[I].BallCnt = 1;
            ExDict[I].HasRed = (I == 1);
        }

        foreach (XYInfoDef EachXYInfo in XYInfoList) {
            int X = EachXYInfo.X;
            int Y = EachXYInfo.Y;

            ExDict[Y].BallCnt++;
            if (ExDict[X].HasRed) {
                ExDict[Y].HasRed = true;
            }

            ExDict[X].BallCnt--;
            if (ExDict[X].BallCnt == 0) {
                ExDict[X].HasRed = false;
            }
        }

        Console.WriteLine(ExDict.Values.Count(pX => pX.HasRed));
    }
}


解説

オセロセットで考察すると
期待値DPを行い、
赤玉の期待値が、0より大きい箱の個数が解と分かります。

しかし、期待値をdecimal型で持って期待値DPをすると
少なすぎる期待値が誤差で0になってしまうので、
期待値が0以上かのみ管理してます。

赤玉が1回でも入った箱は、玉の数が0になるまで
期待値は0より大きいので、
玉の数と赤玉の有無を、クラスで管理してます。