205AC - ABC042C: Iroha's Obsession

ABC042-C (300 points)
問題

 N 以上の整数のうち,  D = \{ d_1, \ldots, d_k \} を含まない最小の整数を求める.

  •  1 \leq N \leq 10000
  •   \leq k \leq 10
  •  0 \leq d_1 < d_2 < \ldots < d_k \leq 9
  •  \{ d_1, d_2, \ldots, d_k \} \neq \{ 1, 2, 3, 4, 5, 6, 7, 8, 9 \}
  • 入力は全て整数
方針

素直にやると...

  • 置換が必要な桁のうち, 最大のものを求める.
  • その桁より上で置換可能( D に含まれない数で置換してより大きい数にすることが可能)な桁を求める.
  • 置換する.

問題をそのまま実装するとよりスッキリ(issubset)

# input
n, k = map(int, input().split())
D = list(map(int, input().split()))

N = [int(x) for x in list(str(n))]
D_inv = sorted(list(set(range(10)) - set(D)))

m = len(N) + 1 # 置換する桁
for i in range(len(N)):
    if N[i] in D:
        m = i
        break

if m == len(N) + 1:
    print(n)
    exit()

n = len(N) + 1 # 置換可能な桁 
for i in range(m + 1):
    if N[i] < D_inv[len(D_inv) - 1]:
        n = i

ans = 0
if n == len(N) + 1: # 置換可能な桁がない場合
    if D_inv[0] == 0:
        ans += D_inv[1] * (10 ** len(N))
    else:
        ans += D_inv[0] * (10 ** len(N))
    for i in range(len(N)):
        ans += D_inv[0] * (10 ** (len(N) - 1 - i))
else:
    for i in range(len(N)):
        if i < n:
            ans += N[i] * (10 ** (len(N) - 1 - i))
        if i == n: 
            for j in D_inv:
                if j > N[i]:
                    ans += j * (10 ** (len(N) - 1 - i))
                    break
        if i > n:
            ans += D_inv[0] * (10 ** (len(N) - 1 - i))
print(ans)
# input
n, k = map(int, input().split())
D = input().split()
D_inv = set([str(i) for i in range(10)]) - set(D)

ans = n
while not set(list(str(ans))).issubset(D_inv):
    ans += 1
print(ans)