AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC122-C GeT AC
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 3");
WillReturn.Add("ACACTACG");
WillReturn.Add("3 7");
WillReturn.Add("2 3");
WillReturn.Add("1 8");
//2
//0
//3
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
string S = InputList[1];
int UB = S.Length - 1;
int[] RunSumArr = new int[UB + 1];
for (int I = 1; I <= UB; I++) {
if (S[I] == 'C' && S[I - 1] == 'A') {
RunSumArr[I]++;
}
}
// 累積和を求める
for (int I = 1; I <= UB; I++) {
RunSumArr[I] += RunSumArr[I - 1];
}
// クエリに回答する
foreach (string EachStr in InputList.Skip(2)) {
SplitAct(EachStr);
int L = wkArr[0] - 1;
int R = wkArr[1] - 1;
// Lが文字Cの位置の場合は、Lをインクリメントする
if (S[L] == 'C') L++;
Console.WriteLine(RunSumArr[R] - RunSumArr[L]);
}
}
}
解説
クエリにO(1)で回答するために、事前にACの登場数の累積和を求めて
範囲終了でのAC登場数から範囲開始でのAC登場数を引いてます。
コーナーケースとして、範囲開始がCの場合は、
範囲開始を1つインクリメントしてます。