AtCoder Beginner Contest 076 C – Dubious Document 2 をPython3で解く

Share

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

出典:
AtCoder Beginner Contest 076 C – Dubious Document 2

正規表現を使ってもいけそうな気はするけど……どちらかというと文字列処理に関わる、真面目な実装力が問われる問題かと思われる。

# AtCoder Beginner Contest 076 C - Dubious Document 2
# https://atcoder.jp/contests/abc076/tasks/abc076_c
# tag: 文字列 辞書順 正規表現

# 自明なこととして、辞書順最小を目指すので、? は可能な限り a に
# 変えるほうがいい。

# しかし、T と一致する部分が最低一箇所は必要。
# 一致箇所が複数ある場合を考える。
# 便宜的に左と右で考えてみると、左側で一致させる場合よりも、
# 右側で一致させるほうが、より左側の ? を a に変更することが
# できる。よって、可能な限り右側で一致させるほうがいい。

# ちなみに公式解説では置き換え可能な全てを求め、
# その中で辞書順最小を出力、としている。
# 制約も緩いので、どちらでもいいかと思う。

def main():
    S = input()
    T = input()

    # T との置換を始める地点を result とする
    result = -1

    # S 上の、|S| - |T| の地点から左に向かって、そこから右の文字列が
    # T と一致 or 置換可能かどうかを探索していく。
    # '(c|?)(o|?)(d|?)...' という感じで組み立てて、正規表現で
    # やってしまう手もあるかもしれないが、やや煩雑かも。
    for start in range(len(S) - len(T), -1, -1):
        for i in range(len(T)):
            # 一文字ずつ一致 or 置換可能かどうかを確認
            if S[start + i] == T[i] or S[start + i] == '?':
                continue
            # 不一致ならスタート地点を左へずらす
            else:
                break

        # 全文字が一致 or 置換可能なら、result を出して break
        else:
            result = start
            break
    
    # result が -1 のままなら、T への置換が不可能
    if result == -1:
        print('UNRESTORABLE')

    # result に値があれば、そこからを T へ置き換え、
    # 他の ? は a に置換して出力
    else:
        S = S.replace('?', 'a')
        print(S[:result] + T + S[result+len(T):])

main()
Share

コメントを残す

メールアドレスが公開されることはありません。