코딩딩/BOJ
[백준 1600번 말이 되고픈 원숭이] 문제풀이
전낙타
2024. 7. 30. 15:06
import sys
from collections import deque
input = sys.stdin.readline
'''
평범한 BFS에서 약간의 응용이 들어감
horse의 움직임과 monkey의 움직임을 저장
함수에 들어가기 전 0으로 초기화된 그래프 생성
visited, queue 초기화
여기서 queue에 들어갈 인자는 x,y 뿐만 아니라 말처럼 움직일 수 있는 횟수, 지금까지 움직인 횟수까지
curY, curX, horseCount, curMove = queue에 들어있는 값을 빼온다
만약 horseCount가 유효하면 > 0
horse 이동방식으로 graph에 족적 남기고 queue에 위치 더하기 - 함수로 빼놓으면 가독성 올라갈듯
horseCount -= 1
아니면
원숭
탐색이 끝나면 graph[h-1][w-1] 출력
global
원숭, 말 이동 패턴
0으로 초기화된 graph
입력받은 graph
local
각 queue에 들어갈 인자들
방문을 처리할 set 하나
문제발생!
말을 아껴놨다가 장애물을 넘어갈 수 있는 위치에서만 사용할 수 있게 구현해야함
한차원 높혀서 모든 경우의 수를 판단해야할듯
visited에 horseCount를 포함해 원숭이 -> 말 -> 원숭이 이런 연산도 가능하게 바꿔야함
'''
horseDY = [-2, -1, -2, -1, 2, 1, 2, 1]
horseDX = [-1, -2, 1, 2, -1, -2, 1, 2]
monkeyDY = [-1, 1, 0, 0]
monkeyDX = [0, 0, -1, 1]
K = int(input())
W, H = map(int, input().split())
def likeMonkey(y, x, horseCount, queue, visited, moves):
for i in range(4):
newY, newX = y + monkeyDY[i], x + monkeyDX[i]
if 0 <= newY < H and 0 <= newX < W and graph[newY][newX] == 0 and (newY, newX, horseCount) not in visited:
queue.append((newY, newX, horseCount, moves + 1))
visited.add((newY, newX, horseCount))
def likeHorse(y, x, horseCount, queue, visited, moves):
for i in range(8):
newY, newX = y + horseDY[i], x + horseDX[i]
if 0 <= newY < H and 0 <= newX < W and graph[newY][newX] == 0 and (newY, newX, horseCount -1) not in visited:
queue.append((newY, newX, horseCount - 1, moves + 1))
visited.add((newY, newX, horseCount - 1))
def bfs():
# 여기서 queue에 들어갈 인자는 x,y 뿐만 아니라 말처럼 움직일 수 있는 횟수, 지금까지 움직인 횟수까지
queue = deque([(0, 0, K, 0)])
visited = {(0, 0, K)}
while queue:
curY, curX, horseCount, moves = queue.popleft()
if curY == H - 1 and curX == W - 1:
return moves
likeMonkey(curY, curX, horseCount, queue, visited, moves)
if horseCount > 0:
likeHorse(curY, curX, horseCount, queue, visited, moves)
return -1
graph = []
for _ in range(H):
graph.append(list(map(int, input().split())))
print(bfs())