[BOJ/Python]1926号図



この問題は最初は深さ優先の探索で接近した.アクセス処理リストの代わりに、紙リスト自体で決定されたインデックスを0に変更し、その領域の幅を計算することによって再帰関数を呼び出す.この方法ですぐに解決した.
import sys
sys.setrecursionlimit(10**9)
def dfs(y, x, cnt):
    paper[y][x]=0
    for i in range(4):
        ny=y+dy[i]
        nx=x+dx[i]
        if ny>=0 and nx>=0 and ny<n and nx<m:
            if paper[ny][nx]==1:
                cnt=dfs(ny, nx, cnt+1)
    return cnt
n, m=map(int, input().split())
paper=[]
for _ in range(n):
    paper.append(list(map(int, input().split())))
dy=[0, 0, -1, 1]
dx=[1, -1, 0, 0]
answer=0
cnt=0
for i in range(n):
    for j in range(m):
        if paper[i][j]==1:
            answer=max(answer, dfs(i, j, 1))
            cnt+=1
print(cnt)
print(answer)
しかし、このプロセスではメモリが超過します.メモリを減らす方法でコードを変更およびコミットしようと何度も試みたが、メモリオーバーフローの問題は解決できなかった.そこで調べたところ,入力の大きさはn(1≦n≦500),m(1≦m≦500)であり,再帰的には解決できないことが分かった.DFSを勉強しているのでDFSで解決しようと思いますが、もっと早いBFSで解決します.
BFSもDFSの使い方と変わらない.DFSの再帰呼び出しとは異なり、BFSはキューに値を追加するようにナビゲートします.
  • キューを使用するためにdequeが取得されます.
  • bfs関数をy,xをパラメータとして宣言した.
    ->paper[y][x]が0に更新されました.
    ->qをQとする.
    ->qに(y,x)を加える.
    ->変数cntを1と宣言して領域の幅を求める.
    ->qが空でない場合は繰り返し、ドアを回します.
    -->y、xはq.popleft()の戻り値を格納する.
    -->4回繰り返したiに対してfor文を回します.
    ----->nyにはy+dy[i]が格納されている.
    -->nxにはx+dx[i]が格納されている.
    -->ny、nxが0以上、nyがn未満、nxがm未満、paper[ny][nx]が1以下の場合、
    ------>qに(ny,nx)を加える.
    ------>paper[ny][nx]が0に更新されました.(オンサイトサービス)
    ------>cnt 1を増やします.(領域サイズを増やす)
    ->cntを返します.
  • nとmを入力します.
  • 図画紙の画像情報を受け取ったリストを読み上げる.
  • n回のfor文を繰り返します.
    ->用紙を入力します.
  • 4種類の移動方向情報のリストdy,dxを保存し,4種類の方向をペアリングして記憶することを発表した.
  • 回答は0です.
  • cntはゼロと発表した.
  • n回繰り返したiに対してfor文を行う.
    ->mループのjのfor文.
    -->paper[i][j]が1の場合、
    ----->答えを答えに更新し、bfs(i,j)より大きな値にします.
    -->cntは1を増やします.
  • 出力
  • cnt.
  • の回答を印刷します.
  • Code

    from collections import deque
    def bfs(y, x):
        paper[y][x]=0
        q=deque()
        q.append((y,x))
        cnt=1
        while q:
            y, x=q.popleft()
            for i in range(4):
                ny=y+dy[i]
                nx=x+dx[i]
                if ny>=0 and nx>=0 and ny<n and nx<m and paper[ny][nx]==1:
                    q.append((ny, nx))
                    paper[ny][nx]=0
                    cnt+=1
        return cnt
    n, m=map(int, input().split())
    paper=[]
    for _ in range(n):
        paper.append(list(map(int, input().split())))
    dy=[0, 0, -1, 1]
    dx=[1, -1, 0, 0]
    answer=0
    cnt=0
    for i in range(n):
        for j in range(m):
            if paper[i][j]==1:
                answer=max(answer, bfs(i, j))
                cnt+=1
    print(cnt)
    print(answer)