AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC141-A Periodic Number
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("3");
WillReturn.Add("1412");
WillReturn.Add("23");
WillReturn.Add("498650499498649123");
//1313
//22
//498650498650498650
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
foreach (string EachStr in InputList.Skip(1)) {
long Result = Solve(long.Parse(EachStr));
Console.WriteLine(Result);
}
}
static long Solve(long pN)
{
string StrN = pN.ToString();
int StrLen = StrN.Length;
int UB = StrLen - 1;
// 約数を全探索
int[] YakusuuArr = DeriveYakusuuArr(StrLen);
YakusuuArr = Array.FindAll(YakusuuArr, pX => pX < StrLen);
var AnswerKouho = new List<long>();
foreach (int EachYakusuu in YakusuuArr) {
var StrList = new List<string>();
for (int I = 0; I <= UB; I += EachYakusuu) {
StrList.Add(StrN.Substring(I, EachYakusuu));
}
var LongList = new List<long>();
StrList.ForEach(pX => LongList.Add(long.Parse(pX)));
var sb = new System.Text.StringBuilder();
while (sb.Length < StrLen) {
sb.Append(LongList[0]);
}
long Kouho = long.Parse(sb.ToString());
if (Kouho <= pN) {
AnswerKouho.Add(Kouho);
}
if (Is10Beki(LongList[0])) {
AnswerKouho.Add(long.Parse(new string('9', StrLen - 1)));
}
else {
long MinusVal = LongList[0] - 1;
sb.Length = 0;
while (sb.Length < StrLen) {
sb.Append(MinusVal);
}
AnswerKouho.Add(long.Parse(sb.ToString()));
}
}
return AnswerKouho.Max();
}
// 約数を列挙する
static int[] DeriveYakusuuArr(int pTarget)
{
var YakusuuSet = new HashSet<int>();
for (int I = 1; I * I <= pTarget; I++) {
if (pTarget % I == 0) {
YakusuuSet.Add(I);
YakusuuSet.Add(pTarget / I);
}
}
int[] YakusuuArr = YakusuuSet.ToArray();
Array.Sort(YakusuuArr);
return YakusuuArr;
}
// 10のべき乗かを判定する
static bool Is10Beki(long pVal)
{
long CurrVal = 1;
while (CurrVal <= pVal) {
if (CurrVal == pVal) return true;
CurrVal *= 10;
}
return false;
}
}
解説
長さ12の文字列なら周期として考えられるのは
12の約数の中の12未満の数である
1,2,3,4,6
のいずれかになります。
周期ごとに、先頭の固まりでOKなら
先頭の固まりを解候補とし、
先頭の固まりでNGなら、
先頭の固まりから1引いた数を候補としてます。
ただし、先頭の固まりが10のべき乗の時は、
全体の文字数から1引いた長さの
連続した9が解候補になります。