AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC171-C One Quadrillion and One Dalmatians
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("2");
//b
}
else if (InputPattern == "Input2") {
WillReturn.Add("27");
//aa
}
else if (InputPattern == "Input3") {
WillReturn.Add("123456789");
//jjddja
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
long N = long.Parse(InputList[0]);
Solve(N);
}
static void Solve(long pN)
{
// 文字数ごとの場合の数を求める
var StrPatternCntDict = new Dictionary<int, long>();
long StrPatternCnt = 1;
long RumSum = 0;
for (int I = 1; I < int.MaxValue; I++) {
StrPatternCnt *= 26;
StrPatternCntDict[I] = StrPatternCnt;
RumSum += StrPatternCnt;
if (pN <= RumSum) break;
}
// 全体でN項目の文字列が、その文字数の群数列の何番目かを求める
long PrevRumSum = 0;
int[] KeysArr = StrPatternCntDict.Keys.ToArray();
Array.Sort(KeysArr);
for (int I = 0; I <= KeysArr.GetUpperBound(0) - 1; I++) {
PrevRumSum += StrPatternCntDict[KeysArr[I]];
}
// その文字数の群数列の番目
long TargetBanme = pN - PrevRumSum;
string Answer = DeriveAnswer(TargetBanme, KeysArr.Max());
Console.WriteLine(Answer);
}
// 群数列の番目と、何文字の群数列かを引数として、解を返す
static string DeriveAnswer(long pBanme, long pKetaSuu)
{
long CurrVal = pBanme - 1;
var CharList = new List<char>();
do {
long ModVal = CurrVal % 26;
CharList.Add((char)('a' + ModVal));
CurrVal /= 26;
} while (CurrVal > 0);
CharList.Reverse();
string wkStr = new string(CharList.ToArray());
wkStr = wkStr.PadLeft((int)pKetaSuu, 'a');
return wkStr;
}
}
解説
1文字の群数列
2文字の群数列
3文字の群数列
といった数列になってるとして、
最初に、どの群数列に所属しているかを求めて、
次に、群数列の番目に対応する26進数として求めてます。