Official

H - コンベア/Conveyor Editorial by tatyam


グリッドを \(HW\) 頂点の有向グラフに変換して考えます。

マス \((a, b)\) からマス \((r, c)\) に動かせるかどうかは、 マス \((a, b)\) から BFS / DFS などで探索することによって調べることができます。
しかし、全てのマスから探索をすると計算量が \(O((HW)^2)\) になり TLE してしまいます。

マス \((a, b)\) からマス \((r, c)\) に動かせるということは、マス \((r, c)\) から辺を逆にたどってマス \((a, b)\) に辿り着けることと同値です。
そこで、グラフの全ての辺を逆向きにして、マス \((r, c)\) から BFS / DFS などで探索すると、 \(O(HW)\) で解くことができます。

回答例 (Python)

from collections import deque
import sys

H, W = map(int, input().split())
N = H * W
r, c = map(int, input().split())
at = (r - 1) * W + (c - 1)
s = sys.stdin.read().replace('\n', '')
g = [list() for i in range(N)]

for i in range(H):
    for j in range(W):
        x = i * W + j
        if s[x] in ".^" and i > 0:
            g[x - W].append(x)
        if s[x] in ".<" and j > 0:
            g[x - 1].append(x)
        if s[x] in ".>" and j + 1 < W:
            g[x + 1].append(x)
        if s[x] in ".v" and i + 1 < H:
            g[x + W].append(x)

reachable = [False] * N
reachable[at] = True
q = deque([at])
while q:
    at = q.popleft()
    for i in g[at]:
        if not reachable[i]:
            reachable[i] = True
            q.append(i)

write = sys.stdout.write
for i in range(H):
    for j in range(W):
        x = i * W + j
        if s[x] == '#':
            write('#')
        elif reachable[x]:
            write('o')
        else:
            write('x')
    write('\n')

posted:
last update: