PS

백준 21736번: 헌내기는 친구가 필요해 [실버 3] - Python

Alsong 2023. 11. 12. 16:46

풀이

 

DFS, 혹은 BFS로 풀 수 있겠습니다. 일단 저는 DFS로 먼저 접근해 보았는데요,

 

정답 코드 (DFS)

import sys
sys.setrecursionlimit(1000000)
input = sys.stdin.readline

n, m = map(int, input().split())
graph = [list(input().strip()) for _ in range(n)]

visited = [[0] * m for _ in range(n)]
cnt = 0


def dfs(r, c):
    global cnt
    if r < 0 or r >= n or c < 0 or c >= m:
        return
    if visited[r][c] == 1:
        return
    if graph[r][c] == 'X':
        return
    visited[r][c] = 1
    if graph[r][c] == 'P':
        cnt += 1
    dfs(r - 1, c)
    dfs(r + 1, c)
    dfs(r, c - 1)
    dfs(r, c + 1)


start = (0, 0)
for i in range(n):
    for j in range(m):
        if graph[i][j] == 'I':
            start = (i, j)

dfs(start[0], start[1])

if cnt == 0:
    print("TT")
if cnt != 0:
    print(cnt)

 

 

시간이 꽤나 오래 걸립니다. 캠퍼스 크기가 600x600이나 되어서 탐색하는 데 오래 걸리는 것 같네요. 게다가 기본으로 설정된 재귀 제한 1000으로는 택도 없는 것 같습니다. 그래서 꼭 sys.setrecursionlimit()함수를 써서 재귀제한을 늘려야 합니다.

저는 처음에 10,000으로 늘렸는데, 여전히 제한이 걸려서 100,000으로 늘렸다가 또 안 돼서 1,000,000으로 늘리니까 성공했습니다. 엄청 깊게 들어가는 것 같아요.

 

풀고 나서 다른 분들의 정답 코드를 봤는데, BFS로 푸신 분들은 저보다 약 1/3가량 속도가 빠르더라구요. 그래서 저도 BFS로도 다시 풀어봤습니다.

 

정답 코드 (BFS)

import sys
from collections import deque

input = sys.stdin.readline

n, m = map(int, input().split())
graph = [list(input().strip()) for _ in range(n)]

visited = [[0] * m for _ in range(n)]
cnt = 0


def bfs(row, col):
    global cnt
    move = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    dq = deque()
    dq.append((row, col))
    visited[row][col] = 1
    while dq:
        r, c = dq.popleft()
        for i in range(4):
            nr = r + move[i][0]
            nc = c + move[i][1]
            if nr < 0 or nr >= n or nc < 0 or nc >= m:
                continue
            if graph[nr][nc] == 'X':
                continue
            if visited[nr][nc] == 1:
                continue
            visited[nr][nc] = 1
            dq.append((nr, nc))
            if graph[nr][nc] == 'P':
                cnt += 1

start = (0, 0)
for i in range(n):
    for j in range(m):
        if graph[i][j] == 'I':
            start = (i, j)

bfs(start[0], start[1])

if cnt == 0:
    print("TT")
if cnt != 0:
    print(cnt)

 

BFS로 풀었더니? 역시나 시간도 1/3로 줄고 메모리도 절반 이상 줄었습니다. BFS가 DFS보다 전반적으로 속도가 빠르다고 하니, 그 영향인 것 같습니다.