[백준/Python] DFS/BFS-2178번. 미로탐색

2024. 10. 9. 14:29·코딩테스트/BAEKJOON
728x90
반응형

📌 문제 설명 

NxM크기의 배열로 표현되는 미로가 있다. 
 
미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타낸다. 이러한 미로가 주어졌을 때, (1,1)에서 출발하여 (N,M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 프로그램을 작성하시오. 한 칸에서 다른 칸으로 이동할 때, 서로 인접한 칸으로만 이동할 수 있다. 
아래의 예에는 15칸을 지나야 (N,M)의 위치로 이동할 수 있다. 칸을 셀 때에는 시작 위치와 도착 위치도 포함한다. N×M크기의 배열로 표현되는 미로가 있다.

# 입력

첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각가의 수들은 붙어서 입력으로 주어진다. 

 

# 출력 

첫째 줄에 지나야 하는 최소의 칸 수를 출력한다. 항상 도착 위치로 이동할 수 있는 경우만 입력으로 주어진다. 
 

📌 풀이 코드

# 정답

=> 최단 거리를 탐색하는 문제니까, BFS가 옳다고 생각했다. 

  • dx, dy로 현재 (x,y)에 대해 상하좌우에 대해 탐색할 수 있도록 한다. 
  • nextX, nextY = (x,y)의 상하좌우 좌표
    • 만약 방문했던 (x,y)이면 continue
    • ✅ 아닌 경우, 그래프 값이 1인지 확인하고
    • ✅ 맞으면 큐에 append하고 해당 위치에 몇번째 방문한 블록인지 저장한다. 
      • => 방문한 이전 좌표 값에 1을 더하면 된다!!!
N, M = map(int, input().split())
graph = []
visited = [[False]*M for _ in range(N)]
for i in range(N):
    graph.append(list(map(int, input())))
# for row in graph: 
#    print(row)
end = [N-1, M-1]
# 상x-1y 하x+1y좌xy-1우xy+1 
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
q = []
# 상 하 좌 우로 움직였을 때, 배열을 벗어나지 않으면 
# 거기에 통로가 있는지 graph == 1 보고 맞으면 bfs 또 수행 
def bfs(x,y):
    q.append((x,y))
    # count = 0
    while q:
        x, y = q.pop(0)
        visited[x][y] = True 
        # print(f"ABOUT (x,y) = {x}, {y}")
        if end == [x,y]: 
            return graph[N-1][M-1]
            # print("END")   
            #return (count) 
        for i in range(4):
            nextX, nextY = x+dx[i], y+dy[i]
            if 0<=nextX<N and 0<=nextY<M:
                # print(f"\tABLE nextX, nextY = {nextX}, {nextY}")
                if visited[nextX][nextY]:
                    #print("\t\t\tALREADY VISITED")
                    continue
                if graph[nextX][nextY] == 1: 
                    q.append((nextX, nextY))
                    graph[nextX][nextY] = graph[x][y] + 1
                    # count += 1
                    # print(f"\t\tPOSSIBLE count = {count} q.append(({nextX}, {nextY}))")
                    
print(bfs(0, 0))

#시도1. <실패>

(주석(#)은 테스팅 코드임.)

  • 실패한 이유: count가 방문하는 블록마다 1씩 증가되는데, 테스팅 코드를 돌려보면 코드 아래 글과 같다. 
  • 이때 (1,4) 방문 이후 (0,5)는 방문할 때 count를 세면 안되는데 count를 안 세게 할 방법이 없음. 
  • 따라서, 그래프 내 블록에 방문횟수를 직접 저장하며 가는 게 정답이다. 
N, M = map(int, input().split())
graph = []
visited = [[False]*M for _ in range(N)]
for i in range(N):
    graph.append(list(map(int, input())))
# for row in graph: 
#    print(row)
end = [N-1, M-1]
# 상x-1y 하x+1y좌xy-1우xy+1 
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
q = []
# 상 하 좌 우로 움직였을 때, 배열을 벗어나지 않으면 
# 거기에 통로가 있는지 graph == 1 보고 맞으면 bfs 또 수행 
def bfs(x,y):
    q.append((x,y))
    count = 0
    while q:
        x, y = q.pop(0)
        visited[x][y] = True 
        count += 1
        # print(f"ABOUT (x,y) = {x}, {y}")
        if end == [x,y]: 
            # print("END")
            return (count)
        for i in range(4):
            nextX, nextY = x+dx[i], y+dy[i]
            if 0<=nextX<N and 0<=nextY<M:
                # print(f"\tABLE nextX, nextY = {nextX}, {nextY}")
                if visited[nextX][nextY]:
                    # print("\t\t\tALREADY VISITED")
                    continue
                if graph[nextX][nextY] == 1: 
                    q.append((nextX, nextY))
                    # print(f"\t\tPOSSIBLE count = {count} q.append(({nextX}, {nextY}))")
                    # visited[nextX][nextY] = True
                    # graph[nextX][nextY] = graph[x][y] + 1
print(bfs(0, 0))

=> 테스팅 코드를 포함해 돌려보았을 때, 아래와 같음. 

4 6
101111
101010
101011
111011
[1, 0, 1, 1, 1, 1]
[1, 0, 1, 0, 1, 0]
[1, 0, 1, 0, 1, 1]
[1, 1, 1, 0, 1, 1]
ABOUT (x,y) = 0, 0
        ABLE nextX, nextY = 1, 0
                POSSIBLE count = 1 q.append((1, 0))
        ABLE nextX, nextY = 0, 1
ABOUT (x,y) = 1, 0
        ABLE nextX, nextY = 0, 0
        ABLE nextX, nextY = 2, 0
                POSSIBLE count = 2 q.append((2, 0))
        ABLE nextX, nextY = 1, 1
ABOUT (x,y) = 2, 0
        ABLE nextX, nextY = 1, 0
        ABLE nextX, nextY = 3, 0
                POSSIBLE count = 3 q.append((3, 0))
        ABLE nextX, nextY = 2, 1
ABOUT (x,y) = 3, 0
        ABLE nextX, nextY = 2, 0
        ABLE nextX, nextY = 3, 1
                POSSIBLE count = 4 q.append((3, 1))
ABOUT (x,y) = 3, 1
        ABLE nextX, nextY = 2, 1
        ABLE nextX, nextY = 3, 0
        ABLE nextX, nextY = 3, 2
                POSSIBLE count = 5 q.append((3, 2))
ABOUT (x,y) = 3, 2
        ABLE nextX, nextY = 2, 2
                POSSIBLE count = 6 q.append((2, 2))
        ABLE nextX, nextY = 3, 1
        ABLE nextX, nextY = 3, 3
ABOUT (x,y) = 2, 2
        ABLE nextX, nextY = 1, 2
                POSSIBLE count = 7 q.append((1, 2))
        ABLE nextX, nextY = 3, 2
        ABLE nextX, nextY = 2, 1
        ABLE nextX, nextY = 2, 3
ABOUT (x,y) = 1, 2
        ABLE nextX, nextY = 0, 2
                POSSIBLE count = 8 q.append((0, 2))
        ABLE nextX, nextY = 2, 2
        ABLE nextX, nextY = 1, 1
        ABLE nextX, nextY = 1, 3
ABOUT (x,y) = 0, 2
        ABLE nextX, nextY = 1, 2
        ABLE nextX, nextY = 0, 1
        ABLE nextX, nextY = 0, 3
                POSSIBLE count = 9 q.append((0, 3))
ABOUT (x,y) = 0, 3
        ABLE nextX, nextY = 1, 3
        ABLE nextX, nextY = 0, 2
        ABLE nextX, nextY = 0, 4
                POSSIBLE count = 10 q.append((0, 4))
ABOUT (x,y) = 0, 4
        ABLE nextX, nextY = 1, 4
                POSSIBLE count = 11 q.append((1, 4))
        ABLE nextX, nextY = 0, 3
        ABLE nextX, nextY = 0, 5
                POSSIBLE count = 11 q.append((0, 5))
ABOUT (x,y) = 1, 4
        ABLE nextX, nextY = 0, 4
        ABLE nextX, nextY = 2, 4
                POSSIBLE count = 12 q.append((2, 4))
        ABLE nextX, nextY = 1, 3
        ABLE nextX, nextY = 1, 5
ABOUT (x,y) = 0, 5
        ABLE nextX, nextY = 1, 5
        ABLE nextX, nextY = 0, 4
ABOUT (x,y) = 2, 4
        ABLE nextX, nextY = 1, 4
        ABLE nextX, nextY = 3, 4
                POSSIBLE count = 14 q.append((3, 4))
        ABLE nextX, nextY = 2, 3
        ABLE nextX, nextY = 2, 5
                POSSIBLE count = 14 q.append((2, 5))
ABOUT (x,y) = 3, 4
        ABLE nextX, nextY = 2, 4
        ABLE nextX, nextY = 3, 3
        ABLE nextX, nextY = 3, 5
                POSSIBLE count = 15 q.append((3, 5))
ABOUT (x,y) = 2, 5
        ABLE nextX, nextY = 1, 5
        ABLE nextX, nextY = 3, 5
                POSSIBLE count = 16 q.append((3, 5))
        ABLE nextX, nextY = 2, 4
ABOUT (x,y) = 3, 5
17

 

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'코딩테스트 > BAEKJOON' 카테고리의 다른 글

[백준/Python] DFS/BFS-1697번. 숨바꼭질  (3) 2024.10.12
[백준/Python] DFS/BFS-2644번. 촌수 문제  (2) 2024.10.11
[백준/Python] DFS/BFS-2667번. 단지번호 붙이기  (1) 2024.10.09
[백준/Python] DFS/BFS-2606번. 바이러스  (1) 2024.10.09
[백준/Python] 1260. DFS와 BFS  (2) 2024.10.09
'코딩테스트/BAEKJOON' 카테고리의 다른 글
  • [백준/Python] DFS/BFS-2644번. 촌수 문제
  • [백준/Python] DFS/BFS-2667번. 단지번호 붙이기
  • [백준/Python] DFS/BFS-2606번. 바이러스
  • [백준/Python] 1260. DFS와 BFS
heeya16
heeya16
개발 공부 냠냠
  • heeya16
    개발자 희야
    heeya16
  • 전체
    오늘
    어제
    • 분류 전체보기 (105)
      • 코딩테스트 (66)
        • 프로그래머스 (38)
        • SWEA (2)
        • BAEKJOON (26)
      • 알고리즘 (7)
      • 자료구조 (19)
      • 프로젝트 (5)
      • 취업 주르륵 (2)
      • 데이터베이스 (0)
      • IT지식 (2)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    1003
    10448
    10773
    10월
    10진수
    11047
    11399
    11403
    11866
    1449
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
heeya16
[백준/Python] DFS/BFS-2178번. 미로탐색
상단으로

티스토리툴바