SOMPO HD コンテスト(ABC192 D - Base n)【Python解答例】
SOMPO HD プログラミングコンテスト(ABC192)で解けなかったD問題を復習していきます。
atcoder.jp
AtCoder Beginner Contest192 D - Base n
問題文
0 ~ 9 からなる文字列 X と、整数 M が与えられます。
X に含まれる最も大きい数字を d とします。
d+1 以上の整数 n を選んで X を n 進法表記の数とみなして得られる値のうち、M 以下であるようなものは何種類あるでしょうか?
制約
・X は 0 ~ 9 のみからなる
・X の長さは 1 以上 60 以下
・X の先頭の文字は 0 ではない
・1≤M≤10^18
解答例
x = input() m = int(input()) def Base_n_to_10(X,N): # N進数のXを10進数に変換 out = 0 for i in range(1,len(str(X))+1): out += int(X[-i])*(N**(i-1)) return out d = 0 for i in range(len(x)): # dを求める d = max(d,int(x[i])) n = d if len(x) == 1: # Xが一桁の場合はコーナーケース if int(x) <= m: ans = 1 else: ans = 0 else: # 二分探索 left = n right = m + 1 while right - left > 1: mid = (left + right) // 2 if Base_n_to_10(x,mid) > m: right = mid else: left = mid ans = left - n print(ans)
解説
まずX に含まれる最も大きい数字dを求め、二分探索で答えを求めていきました。
Xが1桁のときはコーナーケースになります。
例えばX =2とするとn = 3なので3進数の2は2のままです。
n = 4にしても4進数の2は2のままなので値は同じになります。
問題文から値の数を答えなければならないので、XがMより小さければ答えは1、大きければ答えは0となります。
Xが2桁以上のときは二分探索をおこないます。
dからm+1の範囲で探索します。
N進数のXを10進数に変換するのはBase_n_to_10関数で行いました。
探索が終わったら求める答えはleft - nとなりますので、それを出力すればACでした。
二分探索の実装がむずかしかったです…
練習がたりませんね (^_^;)
ABC192の関連記事はこちら
ebisuke33.hatenablog.com
ebisuke33.hatenablog.com