카테고리 없음

백준 [2823 유턴 싫어] 파이썬 풀이

oopt1234 2025. 2. 21. 14:12

📌 문제 탐색하기

  • R X C 크기의 지도에 빌딩(X), 도로(.)이 표시되어 있다. 임의의 도로 한 점에서 시작했을 때, 유턴을 하지 않고 시작 지점으로 돌아올 수 있는지 판단하는 문제이다.
  • 문제에서 말하는 유턴이란 (1, 1) 위치에서 (1, 2)로 이동한 후, 바로 다시 (1, 1)로 이동하는 것을 말한다.
  • 즉 유턴을 하지 않고 원점으로 돌아가기 위해서는 현재 위치해 있는 도로와 연결된 다른 도로가 최소 2개 이상이어야 한다.

💡 알고리즘 선택

  • 지도에 있는 임의의 도로에서 BFS를 활용하여 상하좌우에 다른 도로가 2개 이상인지 확인하면 될 것 같다.
  • 모든 도로가 서로 연결되어 있으므로 어느 점에서 시작하든 상관이 없을 것이다.
def BFS(start):
    queue = deque([start])
    visited[start[0]][start[1]] = 1
    while queue:
        count = 0
        x, y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if r > nx >= 0 and c > ny >= 0 and map[nx][ny] == '.':
                count += 1
                
                if visited[nx][ny] == False:
                    visited[nx][ny] = True
                    queue.append((nx, ny))
                    
        if count < 2:
            return 1
        
    return 0
  • 다음과 같이 BFS 내부에서 네 방향을 탐색하고, 각각의 좌표가 유효한 범위이고 도로가 맞으면 count를 1 증가시킨다.
  • 네 방향을 모두 탐색했을 때, count가 2보다 작다면 유턴 없이 원점으로 돌아갈 수 없다고 판단하여 1을 return하고 그렇지 않다면 계속 BFS를 탐색하게 했다. 

📌 코드 설계하기

1. 문제의 input을 받아서 r, c, map을 구현한다.

2. r x c 크기만큼 visited 리스트를 생성하여 방문 유무를 관리한다.

3. 위에 기술했던 것 같이 BFS를 구현하고 임의의 도로부터 탐색을 시작하여 연결된 도로가 2개 이상인지 확인한다.

4. BFS에서 return된 값을 출력한다.

📌 시도 회차 수정 사항 (Optional)

1회차

실수로 BFS 함수 내부에서 count 갯수를 판단할 때, 조건문을 if count < 1로 해버려서 틀렸음.

-> 도로가 2개 이상이어야 유턴 없이 원점으로 돌아갈 수 있으므로 조건문을 if count < 2로 수정함.

 

📌 정답 코드

from collections import deque
r, c = map(int, input().split())

map = []
for i in range(r):
    map.append(input())

visited = [[False] * c for _ in range(r)]

dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]

def BFS(start):
    queue = deque([start])
    visited[start[0]][start[1]] = 1
    while queue:
        count = 0
        x, y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if r > nx >= 0 and c > ny >= 0 and map[nx][ny] == '.':
                count += 1
                
                if visited[nx][ny] == False:
                    visited[nx][ny] = True
                    queue.append((nx, ny))
                    
        if count < 2:
            return 1
        
    return 0

for i in range(r):
    for j in range(c):
        if map[i][j] == '.':
            start = (i, j)

print(BFS(start))