728x90
https://www.acmicpc.net/problem/13460
알고리즘 설명
- 입력 처리:
- n, m을 입력받고 보드 상태를 arr 리스트에 저장합니다.
- 보드를 탐색하면서 빨간 구슬, 파란 구슬, 구멍의 위치를 저장합니다.
- 구슬 이동 함수:
- move(x, y, dx, dy) 함수는 주어진 방향 dx, dy로 구슬을 이동시켜 최종 위치와 이동한 거리를 반환합니다.
- BFS 탐색:
- 초기 상태(빨간 구슬, 파란 구슬 위치, 움직임 횟수)를 큐에 추가합니다.
- 큐에서 상태를 꺼내 네 방향으로 구슬을 이동시키고, 각 방향으로 이동한 후의 상태를 큐에 추가합니다.
- 이동한 후, 파란 구슬이 구멍에 빠지지 않았고 빨간 구슬이 구멍에 빠졌다면 성공을 의미합니다.
- 만약 빨간 구슬과 파란 구슬이 같은 위치에 있다면, 더 많이 이동한 구슬을 한 칸 뒤로 이동시킵니다.
- 방문한 적이 없는 상태라면 그 상태를 큐에 추가합니다.
- 10번 이상 움직여도 빨간 구슬이 구멍에 빠지지 않으면 실패로 간주합니다.
from collections import deque as dq
import sys
input = sys.stdin.readline
# 보드의 세로 크기 n과 가로 크기 m을 입력
n, m = map(int, input().split())
arr = [] # 보드의 상태를 저장할 리스트
# 보드의 상태를 입력받아 arr 리스트에 저장
for i in range(n):
tmp = list(map(str, input().strip())) # 각 줄을 문자열로 입력받아 리스트로 변환
arr.append(tmp) # 변환된 줄을 arr에 추가
for j in range(m):
if tmp[j] == 'R': # 빨간 구슬의 위치
red_x, red_y = i, j
if tmp[j] == 'B': # 파란 구슬의 위치
blue_x, blue_y = i, j
if tmp[j] == 'O': # 구멍의 위치
goal_x, goal_y = i, j
# 구슬을 이동시키는 함수
def move(x, y, dx, dy):
cnt = 0 # 이동한 칸 수를 저장
nx, ny = x, y # 현재 위치를 nx, ny에 저장
# 벽에 부딪히거나 구멍에 도달할 때까지 구슬을 이동
while arr[nx + dx][ny + dy] != '#' and arr[nx][ny] != 'O':
nx += dx # x 방향으로 이동
ny += dy # y 방향으로 이동
cnt += 1 # 이동한 칸 수 증가
return nx, ny, cnt # 최종 위치와 이동한 칸 수를 반환
q = dq() # BFS를 위한 큐를 초기화
# 문제를 해결하는 함수
def solution():
visited = {} # 방문한 상태를 저장할 딕셔너리
direction = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 상하좌우 방향을 저장
q.append([red_x, red_y, blue_x, blue_y, 0]) # 초기 상태를 큐에 추가
while q:
rx, ry, bx, by, cnt = q.popleft() # 큐에서 현재 상태를 꺼냄
if cnt >= 10: # 10번 이상 움직이면 실패
return -1
for dx, dy in direction: # 모든 방향에 대해
# 빨간 구슬과 파란 구슬을 이동
red_nx, red_ny, r_cnt = move(rx, ry, dx, dy)
blue_nx, blue_ny, b_cnt = move(bx, by, dx, dy)
if arr[blue_nx][blue_ny] != 'O': # 파란 구슬이 구멍에 빠지지 않았으면
if arr[red_nx][red_ny] == 'O': # 빨간 구슬이 구멍에 빠지면 성공
return cnt + 1
if red_nx == blue_nx and red_ny == blue_ny: # 두 구슬이 겹치면
if r_cnt > b_cnt: # 이동 거리가 더 긴 구슬을 한 칸 뒤로 이동
red_nx, red_ny = red_nx - dx, red_ny - dy
else:
blue_nx, blue_ny = blue_nx - dx, blue_ny - dy
# 방문한 적이 없는 상태면 큐에 추가
if (red_nx, red_ny, blue_nx, blue_ny) not in visited:
visited[(red_nx, red_ny, blue_nx, blue_ny)] = 1
q.append([red_nx, red_ny, blue_nx, blue_ny, cnt + 1])
return -1 # 모든 경우를 다 탐색했지만 성공하지 못하면 -1을 반환
print(solution())
반응형
'백준 문제풀이 코드저장소 > Gold' 카테고리의 다른 글
Baekjoon 1918. 후위 표기식 / Python (0) | 2024.06.30 |
---|---|
Baekjoon 1700. 멀티탭 스케줄링 / Python (0) | 2024.06.30 |
Baekjoon 2536. 버스 갈아타기 / Python (2) | 2024.06.30 |
Baekjoon 1799. 비숍 / Python (0) | 2024.06.30 |