典型90問
次の典型90問へ
前の典型90問へ
典型90問 058 Original Calculator(★4)
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 3");
//13
}
else if (InputPattern == "Input2") {
WillReturn.Add("0 100");
//0
}
else if (InputPattern == "Input3") {
WillReturn.Add("99999 1000000000000000000");
//84563
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long N = wkArr[0];
long K = wkArr[1];
Console.WriteLine(Solve(N, K));
}
static long Solve(long pN, long pK)
{
if (pN == 0) {
return 0;
}
var AppearList = new List<long>();
var AppearSet = new HashSet<long>();
long[] PreCycleArr;
long[] CycleArr;
long CurrVal = pN;
while (true) {
if (AppearSet.Contains(CurrVal)) {
PreCycleArr = AppearList.TakeWhile(pX => pX != CurrVal).ToArray();
CycleArr = AppearList.SkipWhile(pX => pX != CurrVal).ToArray();
break;
}
AppearList.Add(CurrVal);
AppearSet.Add(CurrVal);
CurrVal = DeriveNextVal(CurrVal);
}
if (pK <= PreCycleArr.Length) {
long PrevVal1 = PreCycleArr[pK - 1];
return DeriveNextVal(PrevVal1);
}
long RestK = pK - PreCycleArr.Length;
long PrevVal2 = CycleArr[(RestK - 1) % CycleArr.Length];
return DeriveNextVal(PrevVal2);
}
// 現在値を引数として、次の値を返す
static long DeriveNextVal(long pCurrVal)
{
long KetaSum = 0;
long NextVal = pCurrVal;
while (pCurrVal > 0) {
KetaSum += pCurrVal % 10;
pCurrVal /= 10;
}
NextVal += KetaSum;
NextVal %= 100000;
return NextVal;
}
}
解説
途中からサイクルのなるので
サイクルを検知するようにしてます。