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つ刻みでの、値の配列を作ります。
配列ごとに独立で尺取法で解くことができます。