AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC140-D Face Produces Unhappiness
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("6 1");
WillReturn.Add("LRLRRL");
//3
}
else if (InputPattern == "Input2") {
WillReturn.Add("13 3");
WillReturn.Add("LRRLRLRRLRLLR");
//9
}
else if (InputPattern == "Input3") {
WillReturn.Add("10 1");
WillReturn.Add("LLLLLRRRRR");
//9
}
else if (InputPattern == "Input4") {
WillReturn.Add("9 2");
WillReturn.Add("RRRLRLRLL");
//7
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
// ランレングス圧縮情報をListで管理
struct RunLenInfo
{
internal bool IsLeft;
internal int RunLen;
}
static List<RunLenInfo> mRunLenList = new List<RunLenInfo>();
static int mK;
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = InputList[0].Split(' ').Select(pX => int.Parse(pX)).ToArray();
mK = wkArr[1];
string S = InputList[1];
// ランレングス圧縮を行う
int StrUB = S.Length - 1;
char PrevChar = S[0];
int StrLen = 0;
for (int I = 0; I <= StrUB; I++) {
if (S[I] != PrevChar) {
RunLenInfo WillAdd;
WillAdd.IsLeft = (PrevChar == 'L');
WillAdd.RunLen = StrLen;
mRunLenList.Add(WillAdd);
StrLen = 0;
PrevChar = S[I];
}
StrLen++;
if (I == StrUB) {
RunLenInfo WillAdd;
WillAdd.IsLeft = (S[I] == 'L');
WillAdd.RunLen = StrLen;
mRunLenList.Add(WillAdd);
}
}
// 文字が1通りしかない場合
if (mRunLenList.Count == 1) {
Console.WriteLine(mRunLenList[0].RunLen - 1);
return;
}
//foreach(RunLenInfo EachRunLenInfo in mRunLenList){
// Console.WriteLine("IsLeft={0},RunLen={1}", EachRunLenInfo.IsLeft, EachRunLenInfo.RunLen);
//}
int ResultEven = SolveEven();
int ResultOdd = SolveOdd();
Console.WriteLine(Math.Max(ResultEven, ResultOdd));
}
// 全ての文字を、ランレングス圧縮した際の0番目(LかR)に揃えた時の得点を返す
static int SolveEven()
{
int CurrScore = mRunLenList.Sum(pX => pX.RunLen - 1);
int RunLenListUB = mRunLenList.Count - 1;
int RestCnt = mK;
// 0番目に合わせるので、奇数の添字を変更
for (int I = 1; I <= RunLenListUB; I += 2) {
if (I == RunLenListUB) {
CurrScore++;
}
else {
CurrScore += 2;
}
// K回までなのでBreak
if (--RestCnt == 0) break;
}
return CurrScore;
}
// 全ての文字を、ランレングス圧縮した際の1番目(LかR)に揃えた時の得点を返す
static int SolveOdd()
{
int CurrScore = mRunLenList.Sum(pX => pX.RunLen - 1);
int RunLenListUB = mRunLenList.Count - 1;
int RestCnt = mK;
// 1番目に合わせるので、偶数の添字を変更
for (int I = 2; I <= RunLenListUB; I += 2) {
if (I == RunLenListUB) {
CurrScore++;
}
else {
CurrScore += 2;
}
// K回までなのでBreak
if (--RestCnt == 0) break;
}
// 0番目の添字を変更
if (RestCnt > 0) {
CurrScore++;
}
return CurrScore;
}
}
解説
RRRLLLRRLLL
をランレングス圧縮すると
R3L3R2L3
でランレングス圧縮した時の、
(数字-1)の総和
が得点と分かります。
ランレングス圧縮した時の
偶数番目と奇数番目のどっちかに揃えるかの
2通りを試してます。
ただし、端に隣接している番目は、試行の最後にする必要があります。