Python/Python 문제
백준) 구슬탈출 - 실패
서영환
2024. 8. 2. 12:42
백준) 구슬탈출
이번 포스팅은 하지 않을 생각이였다. 이유는 내가 답을 찾지 못한 문제여서이다. 그러나 미래의 나를 위하여 문제 접근 방식부터 코드의 각 부분을 해석 한 글을 작성하기로 생각하였다.
- 문제
- 구슬 2개(빨강, 파랑) 중 빨강 구슬을 N * M 배열에 출구 'O'에 도달할 수 있으면 1을 아니면 0을 출력
- 이때 빠져나오는 구슬은 빨강 하나여야 한다
- 또한 도전 기회는 10회 이며 10회를 초과 하면 탈출 실패로 간주 하여 0을 출력
- 기울기는 상하좌우만 되며 기울어졌을 때 모든 구슬이 해당 방향으로 이동
- 구슬은 겹쳐지 않는다
- 문제 풀이
- 먼저 N과 M을 입력 받는 부분 작성
- 이후 N * M의 배열의 값들을 입력 받아 저장하는 부분 작성
- 입력받아 저장하는 부분에서 구슬들의 초기 위치를 저장 기록
- BFS 방식으로 모든 경우의 수를 앞에서 부터 찾기 시작
- 이후 내용은 코드의 주석에 달아 놓겠다
더보기
실패 코드
import sys
from collections import deque
N, M = map(int, sys.stdin.readline().split())
maps = []
R = []
B = []
for i in range(N):
map_add = list(map(str, sys.stdin.readline().strip()))
maps.append(map_add)
if 'R' in map_add or 'B' in map_add:
for j, word in enumerate(map_add):
if word == 'R':
R = [i, j]
if word == 'B':
B = [i, j]
# 구슬의 이동
def moves(x, y, dx, dy, gole_check):
nx, ny = x, y
i = 1
while True:
cnx, cny = x + (i * dx), y + (i * dy)
# 구슬이 맵에서 벗어 나는지와 벽또는 앞의 구슬에 막혔는지 확인
if cnx < 0 or cnx >= N or cny < 0 or cny >= M:
break
elif maps[cnx][cny] in ['#', 'R', 'B']:
break
else:
nx, ny = cnx, cny
# 구슬이 출구를 통과 했는지 확인
if maps[nx][ny] == 'O':
if maps[x][y] == 'R':
gole_check[0] = True
else:
gole_check[1] = True
i += 1
return nx, ny, gole_check
def bfs(R, B):
# 구슬이 출구에 도달 했는 확인 하는 함수
is_gols = [False, False]
dq = deque([0, R, B])
# 구슬의 초기 위치 기록
x1, y1 = R
x2, y2 = B
dx, dy = [-1, 1, 0, 0], [0, 0, -1, 1]
while dq:
count = dq.popleft()
# 기울기의 획수가 10이상면 실패로 종료
if count > 10:
is_gols = [False, False]
return
# 구슬이 이동하기에 맵에 그려진 구슬을 일단 자리 비움
maps[x1][y1] = '.'
maps[x2][y2] = '.'
rx, ry = dq.popleft()
bx, by = dq.popleft()
# 구슬이 받아 변수 값 부터 이동 하기에 초기 위기 셋팅
maps[rx][ry] = 'R'
maps[bx][by] = 'B'
# if count == 6:
# print(count)
# print('\n'.join(map(str, maps)))
for i in range(4):
# 구슬이 출구로 나가지 않은 상태로 가정하기 구슬의 상태 초기화
is_gols = [False, False]
# 어떤 구슬부터 움직일지 확인
if (i == 0 and rx < bx) or (i == 1 and rx > bx) or (i == 2 and ry < by) or (i == 3 and ry > by):
nrx, nry, is_gols = moves(rx, ry, dx[i], dy[i], is_gols)
# 구슬이 동일 한 위치 이면 일단 먼저 해당 구슬 위치 이동
if ry == by or rx == bx:
maps[rx][ry], maps[nrx][nry] = maps[nrx][nry], maps[rx][ry]
nbx, nby, is_gols = moves(bx, by, dx[i], dy[i], is_gols)
# 이동 해두었던 위치 초기화
if ry == by or rx == bx:
maps[rx][ry], maps[nrx][nry] = maps[nrx][nry], maps[rx][ry]
if is_gols[1]: continue
else:
nbx, nby, is_gols = moves(bx, by, dx[i], dy[i], is_gols)
if is_gols[1]: continue
# 구슬이 동일 한 위치 이면 일단 먼저 해당 구슬 위치 이동
if ry == by or rx == bx:
maps[bx][by], maps[nbx][nby] = maps[nbx][nby], maps[bx][by]
nrx, nry, is_gols = moves(rx, ry, dx[i], dy[i], is_gols)
# 이동 해두었던 위치 초기화
if ry == by or rx == bx:
maps[bx][by], maps[nbx][nby] = maps[nbx][nby], maps[bx][by]
# 빨강 구슬만 출구를 이동했다면 함수 종료
if is_gols == [True, False]:
return is_gols
# 파랑 구슬이 출구를 밟았다면 이후 검색은 필요없기에 다음 작업 수행
if is_gols[1]:
continue
# 구슬이 이동이 되었다면 큐에 기록
if rx != nrx or ry != nry or bx != nbx or by != nby:
dq.append(count + 1)
dq.append([nrx, nry])
dq.append([nbx, nby])
# 기존의 위치를 초기화 한 뒤 최초의 상태로 구슬 위치 변경
maps[rx][ry] = '.'
maps[bx][by] = '.'
maps[x1][y1] = 'R'
maps[x2][y2] = 'B'
return is_gols
check = bfs(R, B)
if check == [True, False]:
sys.stdout.write(f'{1}')
else:
sys.stdout.write(f'{0}')
이 문제는 스쿼드방에서 코드리뷰를 진행한다고 하여 일단 실패 한 상태로 둔 후 코드리뷰 후 다시 코드를 작성 하여 통과 해볼 생각이다.
지금으로써는 어디서, 왜 틀렸는지 조차도 이해가 안되는 상황이라 더는 붙잡고 풀 수는 없을거 같다..