ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 13460] 구슬 탈출 2 (Python)
    Algorithm & Problem Solving/삼성 기출 2022. 5. 3. 22:26

    https://www.acmicpc.net/problem/13460

     

    13460번: 구슬 탈출 2

    첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B'

    www.acmicpc.net

     

    문제풀이

    BFS로 해결할 수 있는데, 이때 전형적으로 2차원 배열로 탐색하는 것이 아니라 4차원 배열로 탐색해야 한다. (빨강구슬 x, y 파란구슬 x, y)

     

     

    1. 큐에 (빨강구슬 x, 빨강구슬 y, 파랑구슬 x, 파랑구슬 y) 추가

     

    2. BFS 를 통해 아직 탐색하지 않은 영역 탐색

        - 벽이나 구멍을 만날 때 까지 특정 방향으로 계속 이동 (move함수)

        - 거리가 10 이상이면 continue

        - 파랑구슬이 빠지면 continue

        - 빨강 구슬과 파랑 구슬이 동일한 위치에 존재하면 뒤에 있던 구슬의 위치를 한칸 빼줌

        - 빨강 구슬만 구멍에 도착하면 return

       

    코드

    import sys
    from collections import deque
    
    dx = [0, 1, 0, -1]
    dy = [1, 0, -1, 0]
    
    # 이동할 다음 위치 계산
    def move(x, y, k):
        cnt = 1
        while True:
            cnt += 1
            nx, ny = x + dx[k], y + dy[k]
            # 이동할 위치가 구멍이거나 벽이면 return
            if board[nx][ny] == 'O': return (nx, ny, cnt)
            if board[nx][ny] == '#': return (x, y, cnt - 1)
            x, y = nx, ny
    
    # BFS
    def solution(rx, ry, bx, by):
        dist = [[[[-1] * M for _ in range(N)] for _ in range(M)] for _ in range(N)]
        dist[rx][ry][bx][by] = 0
        q = deque([(rx, ry, bx, by)])
    
        while q:
            rx, ry, bx, by = q.popleft()
            # 거리가 10 이상이면 패스
            if dist[rx][ry][bx][by] > 10: continue
            # 빨간 구슬이 구멍에 도착하면 return
            if board[rx][ry] == 'O': return dist[rx][ry][bx][by]
            for k in range(4):
                nrx, nry, nrd = move(rx, ry, k)
                nbx, nby, nbd = move(bx, by, k)
                # 파란 구슬이 구멍에 빠지면 패스
                if board[nbx][nby] == 'O': continue
                # 빨간 구슬의 다음 위치와 파란 구슬의 다음 위치가 같을 경우, 거리(nrd or nbd)가 큰 것이 더 뒤에 있던 경우임
                # 따라서 이동할 다음 위치를 한칸 뒤로 빼주는 것이 필요
                if (nrx, nry) == (nbx, nby):
                    if nrd > nbd:
                        nrx -= dx[k]
                        nry -= dy[k]
                    else:
                        nbx -= dx[k]
                        nby -= dy[k]
                # 방문 했으면 패스
                if dist[nrx][nry][nbx][nby] != -1: continue
                dist[nrx][nry][nbx][nby] = dist[rx][ry][bx][by] + 1
                q.append((nrx, nry, nbx, nby))
        return -1
    
    if __name__ == '__main__':
        N, M = map(int, sys.stdin.readline().split())
        board = [list(map(str, sys.stdin.readline().rstrip())) for _ in range(N)]
    
        rx, ry, bx, by = -1, -1, -1, -1
        for i in range(N):
            for j in range(M):
                if board[i][j] == 'R':
                    rx, ry = i, j
                if board[i][j] == 'B':
                    bx, by = i, j
        print(solution(rx, ry, bx, by))

     

    결과

     

    문제풀이나 코드에서 이상한 부분 지적은 언제나 환영합니다!

    댓글

Designed by Tistory.