Official

D - Ulam-Warburton Automaton Editorial by en_translator


Let \(T_i\) be the set \(T\) for the \(i\)-th operation. Then the following holds:

  • For all \((x_1,y_1)\in T_{i+1}\) there exists \((x_2, y_2)\in T_i\) such that \(|x_1-x_2|+|y_1-y_2|=1\).
    • In other words, any cell painted in the \((i+1)\)-th operation is adjacent to a cell painted in the \(i\)-th operation.

Therefore, to find \(T_{i+1}\), it is sufficient to inspect the cells adjacent to the cells in \(T_i\).

If \(T_i=\varnothing\), then \(T_{i+1}=\varnothing\), so once we reach \(T_i=\varnothing\) we can stop the iteration. Furthermore, since \(T_1, T_2, \ldots, \) are pairwise disjoint, \(|T_1|+|T_2|+\ldots\leq HW\). Therefore, the problem can be solved in a total of \(O(HW)\) time.

H, W = map(int, input().split())
S = [list(input()) for i in range(H)]


dxdy = [(1, 0), (0, 1), (-1, 0), (0, -1)]


def in_grid(x, y):
    return 0 <= x < H and 0 <= y < W


def count(x, y):
    c = 0
    for dx, dy in dxdy:
        nx, ny = x + dx, y + dy
        if in_grid(nx, ny) and S[nx][ny] == "#":
            c += 1
    return c


for i in range(H * W):
    if i == 0:
        T = []
        for x in range(H):
            for y in range(W):
                if S[x][y] == "." and count(x, y) == 1:
                    T.append((x, y))
    else:
        nT = []
        for x, y in T:
            for dx, dy in dxdy:
                nx, ny = x + dx, y + dy
                if in_grid(nx, ny) and S[nx][ny] == "." and count(nx, ny) == 1:
                    nT.append((nx, ny))
        T = nT

    if len(T) == 0:
        break
    for x, y in T:
        S[x][y] = "#"


ans = 0
for x in range(H):
    for y in range(W):
        ans += int(S[x][y] == "#")

print(ans)

posted:
last update: