おもしろそうなのでやってみました。
# 探索する方向に応じた次に探索する方向:
# 0:South, 1:East, 2:North, 3:West
DIR = ( (0, 1, 3)
,(1, 2, 0)
,(2, 3, 1)
,(3, 0, 2)
)
# 探索する方向に応じたとなりへの差分
D = ( ((1, 0), (0, 1), (0, -1))
, ((0, 1), (-1, 0), (1, 0))
, ((-1, 0), (0, -1), (0, 1))
, ((0, -1), (1, 0), (-1, 0))
)
W, H = map(int, input().split())
A = [ [False] * (W + 2) if i == 0 or i == H + 1 else
[False, *list(map(int, input().split())), False]
for i in range(H + 2)
]
def erase_island(i, j):
A[i][j] = 0
exists = []
for l in range(2):
if A[(ii := i+D[0][l][0])][(jj := j+D[0][l][1])]:
exists.append((l, ii, jj))
A[ii][jj] = 0
for l, ii, jj in exists:
erase_to(DIR[0][l], ii, jj)
def erase_to(k, i, j):
exists = []
for l in range(3):
if A[(ii := i+D[k][l][0])][(jj := j+D[k][l][1])]:
exists.append((l, ii, jj))
A[ii][jj] = 0
for l, ii, jj in exists:
erase_to(DIR[k][l], ii, jj)
ans = 0
for i in range(1,H+1):
for j in range(1,W+1):
if A[i][j] == 0:
continue
ans=ans+1
erase_island(i,j)
print(ans)
島をみつけたらカウントして地図から消していくって感じです。
単純に四方を探索すると被りが出てくるので、とりあえず来た方向には探索しないってのと、一回の探索で正面、左、右の最大3箇所消せるようにしました。
ちょっと複雑になっちゃったけど、その分速くはなってる気がします。