AtCoderのABC    前のABCの問題へ

ABC381-D 1122 Substring


問題へのリンク


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

    static int[] mAArr;

    static void Main()
    {
        List<string> InputList = GetInputList();
        mAArr = InputList[1].Split(' ').Select(pX => int.Parse(pX)).ToArray();

        var AnswerList = new List<int>();

        List<int[]> ValArrList = new List<int[]>();
        ValArrList.AddRange(DeriveValArrList(0));
        ValArrList.AddRange(DeriveValArrList(1));

        int Answer = 0;
        foreach (int[] EachArr in ValArrList) {
            Answer = Math.Max(Answer, ExecSyakutorihou(EachArr));
        }
        Console.WriteLine(Answer * 2);
    }

    // 始点を引数として、2つペアの配列のListを返す
    static List<int[]> DeriveValArrList(int pStaInd)
    {
        var WillReturn = new List<int[]>();

        var CurrList = new List<int>();
        for (int I = pStaInd; I <= mAArr.GetUpperBound(0); I += 2) {
            if (I + 1 <= mAArr.GetUpperBound(0)) {
                if (mAArr[I] == mAArr[I + 1]) {
                    CurrList.Add(mAArr[I]);
                    continue;
                }
            }
            if (CurrList.Count > 0) {
                WillReturn.Add(CurrList.ToArray());
                CurrList.Clear();
            }
        }
        if (CurrList.Count > 0) {
            WillReturn.Add(CurrList.ToArray());
            CurrList.Clear();
        }
        return WillReturn;
    }

    // 尺取法で最長の長さを返す
    static int ExecSyakutorihou(int[] pArr)
    {
        int Answer = 0;
        var ValSet = new HashSet<int>();
        ValSet.Add(pArr[0]);
        int R = 0;
        for (int L = 0; L <= pArr.GetUpperBound(0); L++) {
            while (R + 1 <= pArr.GetUpperBound(0) && ValSet.Add(pArr[R + 1])) {
                R++;
            }
            Answer = Math.Max(Answer, ValSet.Count);
            ValSet.Remove(pArr[L]);
        }
        return Answer;
    }
}


解説

解は、
偶数添字始まりか
奇数添字始まりのどっちかとなります。

なので
添字0から2つ刻みでの、値の配列と
添字1から2つ刻みでの、値の配列を作ります。

配列ごとに独立で尺取法で解くことができます。