AtCoderのABC    次のABCの問題へ    前のABCの問題へ

ABC192-D Base n


問題へのリンク


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("22");
            WillReturn.Add("10");
            //2
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("999");
            WillReturn.Add("1500");
            //3
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("100000000000000000000000000000000000000000000000000000000000");
            WillReturn.Add("1000000000000000000");
            //1
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();

        string X = InputList[0];
        long M = long.Parse(InputList[1]);

        long D = X.ToCharArray().Max(pX => pX - '0');

        if (X.Length == 1) {
            if (long.Parse(X) <= M) {
                Console.WriteLine(1);
            }
            else {
                Console.WriteLine(0);
            }
            return;
        }

        // 二分法で解く
        long L = D + 1;
        if (IsOver(X, M, L)) {
            Console.WriteLine(0);
            return;
        }

        long R = long.MaxValue;

        while (L + 1 < R) {
            long Mid = long.MaxValue / 2;
            if (R < long.MaxValue) {
                Mid = (L + R) / 2;
            }

            if (IsOver(X, M, Mid)) {
                R = Mid;
            }
            else {
                L = Mid;
            }
        }
        Console.WriteLine(L - (D + 1) + 1);
    }

    // XをN進数として、Mを超えるかを返す
    static bool IsOver(string pX, long pM, long pD)
    {
        long Rest = pM;
        long BaseVal = 1;
        int UB = pX.Length - 1;
        for (int I = UB; 0 <= I; I--) {
            if (Rest < BaseVal) return true;
            long CurrNum = (pX[I] - '0') * BaseVal;
            Rest -= CurrNum;
            if (Rest < 0) return true;

            if (0 < I) {
                if (Rest / pD < BaseVal) return true;
                BaseVal *= pD;
            }
        }
        return Rest < 0;
    }
}


解説

Xが1文字かで場合分けして、
その後は、二分法を使ってます。