AtCoderのPAST
次のPASTの問題へ
前のPASTの問題へ
第8回PAST I /2 and *3
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("18 21 46");
//23
}
else if (InputPattern == "Input2") {
WillReturn.Add("5");
WillReturn.Add("3 5 7 11 13");
//3
}
else if (InputPattern == "Input3") {
WillReturn.Add("1");
WillReturn.Add("536870912");
//68630377364883
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] mAArr;
static void Main()
{
List<string> InputList = GetInputList();
mAArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long L = mAArr.Min();
long R = long.MaxValue;
while (L + 1 < R) {
long Mid = (L + R) / 2;
if (CanAchieve(Mid)) {
L = Mid;
}
else {
R = Mid;
}
}
Console.WriteLine(L);
}
// 最小値をK以上にできるかを返す
static bool CanAchieve(long pK)
{
long[] CurrArr = (long[])mAArr.Clone();
// 3倍できる回数
long ProdCnt = 0;
var LowerKList = new List<long>();
// 2を因数に持つ限り、2で割る
for (int I = 0; I <= CurrArr.GetUpperBound(0); I++) {
while (CurrArr[I] % 2 == 0) {
CurrArr[I] /= 2;
ProdCnt++;
}
if (CurrArr[I] < pK) {
LowerKList.Add(CurrArr[I]);
}
}
for (int I = 0; I <= LowerKList.Count - 1; I++) {
while (LowerKList[I] < pK) {
if (ProdCnt == 0) {
return false;
}
LowerKList[I] *= 3;
ProdCnt--;
}
}
return true;
}
}
解説
最小値をK以上にできるかを返すメソッドを作って、
答えを二分探索してます。