AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC136-D Gathering Children
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("RRLRL");
//0 1 2 1 1
}
else if (InputPattern == "Input2") {
WillReturn.Add("RRLLLLRLRRLL");
//0 3 3 0 0 0 1 1 0 2 2 0
}
else if (InputPattern == "Input3") {
WillReturn.Add("RRRLLRLLRRRLLLLL");
//0 0 3 2 0 2 1 0 0 0 4 4 0 0 0 0
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
string S = InputList[0];
var InsRunLen = new RunLen(S);
List<RunLen.RunLenInfo> RunLenList = InsRunLen.GetRunLenList();
// 人数[添字]なDict
var SumDict = new Dictionary<int, int>();
int RunSumInd = 0;
for (int I = 0; I <= RunLenList.Count - 1; I += 2) {
int RCnt = RunLenList[I].RunLen;
int LCnt = RunLenList[I + 1].RunLen;
int StaRind = RunSumInd;
int StaLind = StaRind + RCnt;
// 区間の、偶数添字と奇数添字の個数を求める
int EvenCnt = 0;
int OddCnt = 0;
for (int J = StaRind; J <= StaLind + LCnt - 1; J++) {
if (J % 2 == 0) {
EvenCnt++;
}
else {
OddCnt++;
}
}
if ((StaLind - 1) % 2 == 0) {
SumDict[StaLind - 1] = EvenCnt;
SumDict[StaLind] = OddCnt;
}
else {
SumDict[StaLind - 1] = OddCnt;
SumDict[StaLind] = EvenCnt;
}
RunSumInd = StaLind + LCnt;
}
var WillOutIntList = new List<int>();
for (int I = 0; I <= S.Length - 1; I++) {
if (SumDict.ContainsKey(I) == false) {
WillOutIntList.Add(0);
}
else {
WillOutIntList.Add(SumDict[I]);
}
}
string[] WillOutStrArr = Array.ConvertAll(WillOutIntList.ToArray(), pX => pX.ToString());
Console.WriteLine(string.Join(" ", WillOutStrArr));
}
}
// ランレングス圧縮
internal class RunLen
{
// ランレングス圧縮情報をListで管理
internal struct RunLenInfo
{
internal char AppearChar;
internal int RunLen;
}
private List<RunLenInfo> mRunLenList = new List<RunLenInfo>();
// コンストラクタ
internal RunLen(string pBaseStr)
{
// ランレングス圧縮を行う
int StrUB = pBaseStr.Length - 1;
char PrevChar = pBaseStr[0];
int StrLen = 0;
for (int I = 0; I <= StrUB; I++) {
if (pBaseStr[I] != PrevChar) {
RunLenInfo WillAdd;
WillAdd.AppearChar = PrevChar;
WillAdd.RunLen = StrLen;
mRunLenList.Add(WillAdd);
StrLen = 0;
PrevChar = pBaseStr[I];
}
StrLen++;
if (I == StrUB) {
RunLenInfo WillAdd;
WillAdd.AppearChar = pBaseStr[I];
WillAdd.RunLen = StrLen;
mRunLenList.Add(WillAdd);
}
}
}
// ランレングス圧縮情報を返す
internal List<RunLenInfo> GetRunLenList()
{
return mRunLenList;
}
}
解説
RRRLLRLLRRRLLLLL
で考察すると、
連続したRの最後と、連続したLの最初
で繰り返しがおきることが分かります。
また、各移動は右か左なので
10の100乗といった、偶数回の移動では、
添字の偶奇は一致すると分かります。
以上をふまえて、ランレングス圧縮を行い、
RのランとLのランの組み合わせごとに
解を求めてます。