AtCoder Beginner Contest 099 C – Strange Bank をPython3で解く

Share

AtCoder上にある問題のうち、AtCoder Problemsでdiff 800以上と判定されているものを順番に解いていく企画。
基本的な考え方は全てコード中のコメントに入れてあるので、参照のこと。

出典:
AtCoder Beginner Contest 099 C – Strange Bank

どんな銀行やねん……と突っ込まざるを得ない問題。

# AtCoder Beginner Contest 099 C - Strange Bank
# https://atcoder.jp/contests/abc099/tasks/abc099_c
# tag: N進数

# 6 進数と 9 進数の組み合わせを考える問題。
# 幸い 1 <= N <= 100000 と制約が緩いので、
# 6 進数で数える分と 9 進数で数える分をわけることにして、全探索する。

def main():
N = int(input())

# ある数 x を p 進法で考えたときの
# 各桁の数字の合計を返す関数を作成しておく。
def get_op_num(x, p):
result = 0
while x:
result += x % p
x //= p
return result

result = N
# 9 進法で数える分を 0 ~ N の範囲で動かし、全探索を行う。
# 1 円の桁はどちらで数えても同じなので、9 の倍数だけ調べていく。
for p_nine in range(0, N+1, 9):
tmp = get_op_num(p_nine, 9) + get_op_num(N - p_nine, 6)
if result > tmp:
result = tmp

print(result)

main()

ついでにメモ化再帰でも解いてみた。

# メモ化再帰を用いた場合
import sys
sys.setrecursionlimit(10**9)
def main():
N = int(input())

# dpt[x]: x 円を引き出すために必要な最小回数
dpt = [-1] * (N+1)
dpt[0] = 0

def get_min_op(x):
# メモがあればそれを返す。
if dpt[x] != -1:
return dpt[x]

# 最大は x 回
result = x

# 1 円を引き出す場合
tmp_r = get_min_op(x - 1) + 1
if result > tmp_r:
result = tmp_r

# 9^n 円を引き出す場合
prev = 9
while prev <= x:
tmp_r = get_min_op(x - prev) + 1
if result > tmp_r:
result = tmp_r
prev *= 9

# 6^n 円を引き出す場合
prev = 6
while prev <= x:
tmp_r = get_min_op(x - prev) + 1
if result > tmp_r:
result = tmp_r
prev *= 6

dpt[x] = result
return result

result = get_min_op(N)
print(result)
main()
Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です