AtCoder Regular Contest 120 B – Uniformly Distributed をPython3で解く

Share

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

出典:
AtCoder Regular Contest 120 B – Uniformly Distributed

問題文を読んだ直後はひどく難しそうに感じる問題だが、実際に解くとそうでもない。小さな具体例をいくつか上げていけば、法則には気づけると思う。

# AtCoder Regular Contest 120 B - Uniformly Distributed
# https://atcoder.jp/contests/arc120/tasks/arc120_b
# tag: グリッド 色塗り 特殊構造 順列・組み合わせ 数え上げ

# 次の 3 x 3 の経路を考えてみる。
# 1 2 3
# 4 5 6
# 7 8 9

# 1 4 7 8 9
# 1 4 5 8 9
# という、一個違いの経路について考慮してみると、
# 5 と 7 は同じ色で無ければならない。
# 同様に、1 4 5 6 9 と 1 2 5 6 9 から
# 2 と 4 も同じ色。
# つまり、右上→左下の方向の斜めに隣り合ったマスは、
# すべて同じ色でなければならない。

# ところで、スタートからの距離をプロットすると
# 斜めの模様になることを考慮すると、上記の場合、
# スタートから同じ距離のマスは全て同じ色になる。

# よって、あらゆる経路は全く同じ色のパターンとなり、
# 条件を満たすことになる。

def main():
    H, W = map(int, input().split())
    field = [input() for _ in range(H)]
    MOD = 998244353
    # スタートからの距離別に管理する

    # 0: どちらでもいい 
    # 1: 赤
    # 2: 青
    # 3: 矛盾
    # という感じでビットで色を管理
    color_by_dist = [0] * (H+W-1)

    for h in range(H):
        for w in range(W):
            dist = h + w
            if field[h][w] == 'R':
                color = 1
            elif field[h][w] == 'B':
                color = 2
            else:
                color = 0

            # 色はビット演算のORを利用して更新する
            color_by_dist[dist] |= color

    result = 1
    # 距離別に見ていく
    for d in range(H+W-1):
        # 赤と青の両方の色があれば、矛盾なので 0 を
        # 返して終了する
        if color_by_dist[d] == 3:
            print(0)
            return
        # 色が決定していない時のみ、赤 or 青にできるので、
        # 2 を掛ける
        elif color_by_dist[d] == 0:
            result = (result * 2) % MOD

    print(result)

main()
Share

コメントを残す

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