[Python] 백준 13459번: 구슬 탈출
알고리즘/[Python] 백준

[Python] 백준 13459번: 구슬 탈출

출처 : https://www.acmicpc.net/problem/13459

 

13459번: 구슬 탈출

첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B' 로 이루어져 있다. '.'은 빈 칸을 의미하고, '#'은 공이 이동할 수 없는 장애물 또는 벽을 의미하며, 'O'는 구멍의 위치를 의미한다. 'R'은 빨간 구슬의 위치, 'B'는 파란 구슬의 위치이다. 입력되는 모든 보드

www.acmicpc.net

 

 

 

brute force하게 풀려고 작정하면 이렇게 코드가 길어질수도 있구나

코드의 bfs함수를 자세히 보면

#왼쪽 / #오른쪽 / #위쪽 / #아래쪽 으로 구분되어 있는 단락?(부분)들이 

실상, 같은 form을 가지고 있다는 걸 알 수 있다.

 

같은 form을 가지고 있으니까, 함수 인자를 어떻게 받느냐에 따라

단순화 해서 코드 양을 확 줄일 수 있는 방법이 있지 않을까..?


Code

from collections import deque
 
def bfs():
    queue = deque()
    ## 빨간 구슬 위치, 파란 구슬 위치, 이동 횟수
    queue.append([red[0], red[1], blue[0], blue[1], 0])
    while queue:
        rx, ry, bx, by, count = queue.popleft()
        if count == 10return 0
        ## 왼쪽으로 이동
        T = 0
        for y in range(ry - 1-1-1):
            if board[rx][y] == '#': nrx, nry = rx, y + 1; break
            elif board[rx][y] == 'O': T = 1; break
        for y in range(by - 1-1-1):
            if board[bx][y] == '#': nbx, nby = bx, y + 1; break
            elif board[bx][y] == 'O': T = 2; break
        if T == 0:
            if (nrx, nry) == (nbx, nby):
                if ry < by: nby += 1
                else: nry += 1
            if not ((rx, ry) == (nrx, nry) and (bx, by) == (nbx, nby)):
                queue.append([nrx, nry, nbx, nby, count + 1])
        elif T == 1return 1
        ## 오른쪽으로 이동
        T = 0
        for y in range(ry + 1, m):
            if board[rx][y] == '#': nrx, nry = rx, y - 1; break
            elif board[rx][y] == 'O': T = 1; break
        for y in range(by + 1, m):
            if board[bx][y] == '#': nbx, nby = bx, y - 1; break
            elif board[bx][y] == 'O': T = 2; break
        if T == 0:
            if (nrx, nry) == (nbx, nby):
                if ry < by: nry -= 1
                else: nby -= 1
            if not ((rx, ry) == (nrx, nry) and (bx, by) == (nbx, nby)):
                queue.append([nrx, nry, nbx, nby, count + 1])
        elif T == 1return 1
        ## 위쪽으로 이동
        T = 0
        for x in range(rx - 1-1-1):
            if board[x][ry] == '#': nrx, nry = x + 1, ry; break
            elif board[x][ry] == 'O': T = 1; break
        for x in range(bx - 1-1-1):
            if board[x][by] == '#': nbx, nby = x + 1, by; break
            elif board[x][by] == 'O': T = 2; break
        if T == 0:
            if (nrx, nry) == (nbx, nby):
                if rx < bx: nbx += 1
                else: nrx += 1
            if not ((rx, ry) == (nrx, nry) and (bx, by) == (nbx, nby)):
                queue.append([nrx, nry, nbx, nby, count + 1])
        elif T == 1return 1
        ## 아래쪽으로 이동
        T = 0
        for x in range(rx + 1, n):
            if board[x][ry] == '#': nrx, nry = x - 1, ry; break
            elif board[x][ry] == 'O': T = 1; break
        for x in range(bx + 1, n):
            if board[x][by] == '#': nbx, nby = x - 1, by; break
            elif board[x][by] == 'O': T = 2; break
        if T == 0:
            if (nrx, nry) == (nbx, nby):
                if rx < bx: nrx -= 1
                else: nbx -= 1
            if not ((rx, ry) == (nrx, nry) and (bx, by) == (nbx, nby)):
                queue.append([nrx, nry, nbx, nby, count + 1])
        elif T == 1return 1
    return 0
cs

 

if __name__ == '__main__':
    n, m = map(int, input().split())
    board = [list(input()) for _ in range(n)]
 
    for i in range(1, n - 1):
        for j in range(1, m - 1):
            if board[i][j] == '.' or board[i][j] == '#': continue
            if board[i][j] == 'B':
                blue = [i, j]; board[i][j] = '.'
            elif board[i][j] == 'R':
                red = [i, j]; board[i][j] = '.'
            elif board[i][j] == 'O':
                out = [i, j]
    print(bfs())
cs