| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 123만들기
- 2422번
- 타입스크립트
- 1541번
- 맥주마시면서걸어가기
- 토마토
- 1926번
- 14940번
- 나이트의이동
- 13913번
- 한윤정이 이탈리아에 가서 아이스크림을 사먹는데
- 정리
- 알고리즘
- 1969번
- 5427번
- javascript
- 6593번
- 백준
- 풀이
- node.js
- 17626번
- 2503번
- 20365번
- 자바스크립트
- 타입스크립트 프로그래밍
- 5014번
- 20300번
- 7526번
- 16953번
- 16439번
Archives
- Today
- Total
Sqsung DevLog
[백준] 5427번: 불 - Node.js (자바스크립트) 본문
1. 문제 ㅡ 5427번: 불 (난이도: Gold IV)
5427번: 불
상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에
www.acmicpc.net
2. 풀이 ㅡ Node.js (자바스크립트)
class Queue {
constructor() {
this.q = [];
this.head = 0;
this.tail = 0;
}
push(item) {
this.q[this.tail++] = item;
}
shift() {
this.head++;
return this.q[this.head - 1];
}
isEmpty() {
return this.head === this.tail;
}
}
const [N, ...input] = require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
const dirs = [
[0, 1],
[0, -1],
[1, 0],
[-1, 0],
];
const testCases = (() => {
const cases = [];
let testCaseCount = +N;
while (testCaseCount--) {
const [X, Y] = input
.shift()
.split(' ')
.map(val => +val);
cases.push({ X, Y, maze: input.splice(0, Y).map(row => [...row]) });
}
return cases;
})();
const setFireSpreadTimes = (q, testCase) => {
const { X, Y, maze } = testCase;
const fireRoute = maze.map(row => row.slice());
const checked = Array.from({ length: Y }).map(_ => Array.from({ length: X }, () => false));
while (!q.isEmpty()) {
const [x, y, time] = q.shift();
checked[y][x] = true;
fireRoute[y][x] = time;
for (let i = 0; i < 4; i++) {
const xPos = x + dirs[i][0];
const yPos = y + dirs[i][1];
if (xPos < 0 || yPos < 0 || xPos >= X || yPos >= Y || checked[yPos][xPos] || maze[yPos][xPos] === '#') continue;
fireRoute[yPos][xPos] = time + 1;
checked[yPos][xPos] = true;
q.push([xPos, yPos, time + 1]);
}
}
return fireRoute;
};
const getEscapeTime = (x, y, testCase, fireRoute) => {
const { X, Y } = testCase;
const checked = Array.from({ length: Y }).map(_ => Array.from({ length: X }, () => false));
const queue = new Queue();
queue.push([x, y, 0]);
while (!queue.isEmpty()) {
const [x, y, time] = queue.shift();
checked[y][x] = true;
for (let i = 0; i < 4; i++) {
const xPos = x + dirs[i][0];
const yPos = y + dirs[i][1];
if (xPos < 0 || yPos < 0 || yPos >= Y || xPos >= X) return time + 1;
if (checked[yPos][xPos] || fireRoute[yPos][xPos] === '#' || fireRoute[yPos][xPos] <= time + 1) continue;
checked[yPos][xPos] = true;
queue.push([xPos, yPos, time + 1]);
}
}
return 'IMPOSSIBLE';
};
const solution = () => {
let answers = [];
for (let i = 0; i < +N; i++) {
const { X, Y, maze } = testCases[i];
const fires = new Queue();
for (let y = 0; y < Y; y++) {
for (let x = 0; x < X; x++) {
if (maze[y][x] === '*') fires.push([x, y, 0]);
}
}
const fireRoute = setFireSpreadTimes(fires, testCases[i]);
for (let ny = 0; ny < Y; ny++) {
for (let nx = 0; nx < X; nx++) {
if (maze[ny][nx] === '@') {
answers.push(getEscapeTime(nx, ny, testCases[i], fireRoute));
break;
}
}
}
}
return answers.join('\n');
};
console.log(solution());
2-1. 풀이 설명
이미 풀어본 4179번: 불! 문제와 거의 같은 문제라 복습 차원에서 이전 코드를 보지 않고 빠르게 풀어봤다. 4179번 문제와 다른 점이 있다면, 테스트 케이스가 조금 더 불친절하게 주어져서 사용하기 편하게 가공하는 과정이 추가되었다.
4179번 문제와 마찬가지로 BFS를 두 번 돌면서, 첫 번째에는 이동 가능 칸 별로 불의 이동 시간을 계산하고, 두 번째에서는 상근이의 탈출 가능 여부를 확인하면 된다. (더 자세한 풀이는 4179번: 불! 블로그 게시물 확인)
'Algorithm' 카테고리의 다른 글
| [백준] 1463번: 1로 만들기 - Node.js (자바스크립트) (0) | 2023.06.05 |
|---|---|
| [백준] 11279번: 최대 힙 - Node.js (자바스크립트) (0) | 2023.06.02 |
| [백준] 4179번: 불! - Node.js (자바스크립트) (2) | 2023.06.01 |
| [백준] 10026번: 적록색약 - Node.js (자바스크립트) (0) | 2023.06.01 |
| [백준] 1927번: 최소 힙 - Node.js (자바스크립트) (1) | 2023.05.31 |