미소를뿌리는감자의 코딩
[백준 2024/10/18] 1600번 말이 되고픈 원숭이 본문
728x90
1. 문제
https://www.acmicpc.net/problem/1600
2. 접근 방법
처음에 i, j 로 visited list를 만드는 것을 생각하였다가, k의 값이 유동적일 것이라 힘들 것 같다는 생각을 하였었다.
하지만 3차원 리스트가 존재했기 때문에, 이를 이용하면 되었다.
코드 풀이 중에서 처음 시도는
import queue
를 하는 것이었다. 하지만, 시간 초과와 런타임 에러가 지속되었고 다른 코드를 확인하다가
from collections import deque
를 적용한 코드를 확인하게 되었다.
이에 queue -> deque로 import를 바꾸었고, 통과할 수 있었다.
과연, 둘의 차이가 무엇일까?
- import queue
queue.Queue()로 사용이 된다. 이는 멀티스레딩 환경에서의 큐로 적합하게 이용이 된다.
또한, 멀티스레딩 환경에서의 안전을 보장하기 위해 락 메커니즘을 사용한다. 시간 복잡도가 O(1)이긴 하지만, 스레드 안정성을 보장하기 위한 추가 작업 때문에 성능이 조금 떨어진다. - from collections import deque
deque는 양방향 큐로 양쪽 끝에서 빠르고 효율적인 추가가 가능하다. O(1)의 시간 복잡도를 보장하나, 스레드 안전성을 보장하지 않는다.
따라서, 해당 문제는 싱글 쓰레드에서 실행이 되므로, import queue보다는 from collections import deque를 사용해서 시간적으로 이점을 얻는 것이 낫다.
3. 코드
from collections import deque
q = deque()
def bfs(k):
monkey = [(-1, 0), (1, 0), (0, 1), (0, -1)]
horse = [(-2, -1), (-1, -2), (1, -2), (2, -1), (-2, 1), (-1, 2), (1, 2), (2, 1)]
visited = [[[0 for col in range(w)] for row in range(h)] for depth in range(k+1)]
q.append((0, 0, k, 0))
while q:
i, j, k, cnt = q.popleft()
if visited[k][i][j] == 1:
continue
visited[k][i][j] = 1
if i == h - 1 and j == w - 1:
return cnt
for l, r in monkey:
if 0 <= i + l < h and 0 <= j + r < w and plain[i + l][j + r] == 0 and visited[k][i+l][j+r] == 0:
q.append((i+l, j+r, k, cnt+1))
if k > 0:
for l, r in horse:
if 0 <= i + l < h and 0 <= j + r < w and plain[i + l][j + r] == 0 and visited[k-1][i+l][j+r] == 0:
q.append((i+l, j+r, k-1, cnt+1))
return -1
if __name__ == "__main__":
k = int(input())
w, h = map(int, input().split())
plain = []
for _ in range(h):
plain.append(list(map(int, input().split())))
print(bfs(k))
728x90
'코딩 테스트 > 백준' 카테고리의 다른 글
[백준 2024/10/29] 13549번 숨바꼭질 3 (0) | 2024.10.29 |
---|---|
[백준 2024/10/18] 9655번 돌 게임 (2) | 2024.10.16 |
[백준 2024/10/15] 1463번 1로 만들기 (1) | 2024.10.15 |
[백준 2024/10/14] 1520번 내리막 길 (0) | 2024.10.14 |
[백준 2024/10/13] 1912번 연속합 (0) | 2024.10.13 |