출처 : 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 == 10: return 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 == 1: return 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 == 1: return 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 == 1: return 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 == 1: return 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 |
'알고리즘 > [Python] 백준' 카테고리의 다른 글
[Python] 백준 7576번 토마토 (0) | 2020.06.05 |
---|---|
[Python] 백준 1759번: 암호 만들기 (0) | 2020.05.06 |
[Python] 백준 2583번: 영역 구하기 (0) | 2020.05.06 |
[Python] 백준 2933번: 미네랄 (0) | 2020.05.03 |
[Python] 백준 17822번: 원판 돌리기 (0) | 2020.04.24 |