| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- react상태관리라이브러리
- zustand
- JS우선순위큐
- 최소힙우선순위큐
- 프로그래머스 퍼즐 게임 챌린지
- git
- 충돌 위험 찾기
- 프로그래머스 숫자 타자 대회
- 리렌더링최적화
- react-quill
- 프로그래머스 비밀 암호 해독
- CSS
- react-router-dom
- 프로그래머스 1843
- 컴퓨터네트워크
- 프로그래머스 봉인된 주문
- 프로그래머스 지게차와 크레인
- 프로그래머스 석유 시추
- 프로그래머스 호텔 방 배정
- 서버증설횟수
- C++
- 비동기함수
- 프로그래머스 택배 상자 꺼내기
- react hook
- 비밀 암호 해독
- 프로그래머스 완전범죄
- 다익스트라 Js
- BFS
- 프로그래머스 충돌 위험 찾기
- 프로그래머스 사칙연산
- Today
- Total
leebaek
[프로그래머스 Lv3] 지게차와 크레인 - Javascript 풀이 본문
https://school.programmers.co.kr/learn/courses/30/lessons/388353
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제
특정 컨테이너를 꺼낸 후 남은 컨테이너의 개수 구하는 문제
생각
BFS를 응용해서 지게차가 접근 가능 공간을 큐에 넣고,
그 주변에 특정 컨테이너가 있다면 꺼내는 방식으로 접근했다.
일반적인 BFS라면 "특정 컨테이너가 있다면 꺼내고 해당 공간을 큐에 다시 넣어 확장" 해야하는데,
이 문제는 작업 공간의 너비가 1로 제한된다는 점이 달랐다.
또한, 크레인으로 컨테이너를 꺼낸 뒤
그로 인해 새롭게 접근 가능한 공간을 어떻게 표시할 지도 고민이 필요했다.
시간 복잡도는 O(R x n x m)으로 효율적이라 생각했다.
문제풀이
지게차 작업일 경우 → bfs를 호출한다.
크레인 작업일 경우 → 배열을 순회하며 특정 컨테이너 vis[i][j]에 2를 저장한다.
vis에서 0, 1, 2는 다음과 같은 의미를 가진다.
| 0 | 남은 컨테이너 |
| 1 | 컨테이너를 치운 후 접근 가능한 공간 |
| 2 | 크레인을 이용해 컨테이너를 치운 공간 ( = 접근 가능한 공간 후보 ) |
접근 가능한 공간을 큐에 넣는다.
- 컨테이너 전체를 둘러싼 가상의 외곽 공간을 큐에 넣는다.
if ( i == -1 || i == n || j == -1 || j == m ) queue.push([i, j])


- 이전 작업으로 인해 접근 가능하게 된 공간을 큐에 넣는다.
if ( vis[i][j] == 1 ) queue.push([i, j])
BFS 탐색과정
해당 공간의 상하좌우를 탐색해 특정 컨테이너인지 확인한다.
- 맞다면 해당 공간에 접근 가능하다는 표시를 해준다. vis[nx][ny] = 1
- 크레인 작업으로 vis[nx][ny] = 2인 공간일 경우, 접근 가능하다는 표시 1로 바꾸어 주고 다시 큐에 넣는다.
코드
function solution(storage, requests) {
const n = storage.length
const m = storage[0].length
let vis = Array.from({length : n}).map(() => Array(m).fill(0))
var queue = []
function bfs(req) {
const dx = [0, 1, 0, -1]
const dy = [1, 0, -1, 0]
// 접근 가능한 공간일 경우 큐에 넣기
for(let i=-1; i<=n; i++) {
for(let j=-1; j<=m; j++) {
if ( i == -1 || i == n || j == -1 || j == m ) {
queue.push([i, j])
} else if ( vis[i][j] == 1 ) queue.push([i, j])
}
}
// 접근 가능한 공간 상하좌우에 특정 컨테이너가 있으면 꺼냄
while(queue.length !== 0) {
const [curX, curY] = queue.shift() // pop()으로 써도 ok ( 더 빠름 )
for(let dir=0; dir<4; dir++) {
const nx = curX + dx[dir]
const ny = curY + dy[dir]
if ( nx < 0 || nx >= n || ny < 0 || ny >= m ) continue
if ( vis[nx][ny] == 1 ) continue
if ( storage[nx][ny] == req ) { // 지게차 작업 접근 가능 공간 표시
vis[nx][ny] = 1
}
if ( vis[nx][ny] == 2 ) { // 크레인 작업 후 접근 가능 공간 표시
vis[nx][ny] = 1
queue.push([nx, ny])
}
}
}
}
requests.forEach((req) => {
if ( req.length == 1 ) bfs(req)
else {
for(let i=0; i<n; i++) {
for(let j=0; j<m; j++) {
if ( storage[i][j] == req[0] ) {
vis[i][j] = 2
}
}
}
}
})
return vis.flat().filter((num) => num === 0).length
}
/*
지게차로 컨테이너를 꺼내는 경우 - 접근 가능한 컨테이너만 제거
크레인으로 컨테이너를 꺼내는 경우 - 해당 컨테이너 제거 후 접근 가능 공간인지 확인
100 * 50 * 50
*/
BFS 기반 접근이므로 일반적으로는 shift()를 사용하지만,
이 문제는 탐색 너비가 1로 제한되어 있어 pop()을 사용해도 결과는 동일하다.
따라서 BFS 기반 접근이지만, DFS 방식(pop)으로 구현해도 무방하다.


'PS > 프로그래머스_PS' 카테고리의 다른 글
| [프로그래머스 Lv2] 퍼즐 게임 챌린지 - Javascript 풀이 (1) | 2025.11.08 |
|---|---|
| [프로그래머스 Lv1] 택배 상자 꺼내기 - Javascript (0) | 2025.11.07 |
| [프로그래머스 Lv2] 비밀 암호 해독 - Javascript 풀이 (0) | 2025.11.06 |
| [프로그래머스 Lv2] 완전 범죄 - Javascript 풀이 (0) | 2025.11.04 |
| [프로그래머스 Lv2] 서버 증설 횟수 - Javascript 풀이 (0) | 2025.11.03 |