AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC410-C Rotatable Array
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("5 5");
WillReturn.Add("2 3");
WillReturn.Add("1 2 1000000");
WillReturn.Add("3 4");
WillReturn.Add("2 2");
WillReturn.Add("2 3");
//3
//1
//1000000
}
else if (InputPattern == "Input2") {
WillReturn.Add("1000000 2");
WillReturn.Add("1 1000000 999999");
WillReturn.Add("3 1000000000");
//
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();
SplitAct(InputList[0]);
long N = wkArr[0];
var ValDict = new Dictionary<long, long>();
for (long I = 1; I <= N; I++) {
ValDict[I] = I;
}
long BaseInd = 1;
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
long Type = wkArr[0];
if (Type == 1) {
long P = wkArr[1];
long X = wkArr[2];
long Target = BaseInd + P - 1;
//while (Target > N) { Target -= N; }
if ((Target %= N) == 0) Target = N;
ValDict[Target] = X;
}
if (Type == 2) {
long P = wkArr[1];
long Target = BaseInd + P - 1;
//while (Target > N) { Target -= N; }
if ((Target %= N) == 0) Target = N;
Console.WriteLine(ValDict[Target]);
}
if (Type == 3) {
long K = wkArr[1];
BaseInd += K;
//while (BaseInd > N) { BaseInd -= N; }
if ((BaseInd %= N) == 0) BaseInd = N;
}
}
}
}
解説
配列の先頭位置をmodで考えてシュミレーションしてます。
modの計算は、
中学受験の日暦算で考えると分かりやすいです。
1日後の曜日
2日後の曜日
3日後の曜日
4日後の曜日
5日後の曜日
6日後の曜日
7日後の曜日
8日後の曜日は、1日後の曜日に等しい
9日後の曜日は、2日後の曜日に等しい
N日後の曜日は、下記のIF文で分かります。
if( ( N %= 7 ) == 0) { N = 7; }
このIF文を下記のWhile文で代用すると、値によってはTLEします。
While ( N < 7 ) { N -= 7; }