Algorithm/Coding Test
마인크래프트(백준 코딩테스트 18111번, 구현/브루트포스, NodeJS 풀이)
Bumang
2024. 5. 6. 15:00
https://www.acmicpc.net/problem/18111
문제 수준:
실버2
문제 요약:
lvalue는 세로 N, 가로 M 크기의 집터를 골랐다. 집터 맨 왼쪽 위의 좌표는 (0, 0)이다. 우리의 목적은 이 집터 내의 땅의 높이를 일정하게 바꾸는 것이다. 우리는 다음과 같은 두 종류의 작업을 할 수 있다.
- 좌표 (i, j)의 가장 위에 있는 블록을 제거하여 인벤토리에 넣는다.
- 인벤토리에서 블록 하나를 꺼내어 좌표 (i, j)의 가장 위에 있는 블록 위에 놓는다.
1번 작업은 2초가 걸리며, 2번 작업은 1초가 걸린다. 밤에는 무서운 몬스터들이 나오기 때문에 최대한 빨리 땅 고르기 작업을 마쳐야 한다. ‘땅 고르기’ 작업에 걸리는 최소 시간과 그 경우 땅의 높이를 출력하시오.
문제 풀이 전략:
이런 문제는 객체지향적으로 접근해야한다.
클래스로 캐릭터가 할 수 있는 액션을 잘 정리해놓고 조건마다 실행시키면 의외로 쉽게 답이 나온다.
내 풀이:
let fs = require("fs");
let [meta, ...list] = fs.readFileSync("dev/stdin").toString().trim().split("\n");
const [N, M, B] = meta.split(" ").map(Number);
let maxH = -1;
let minH = 257;
let minTime = null;
let resH = null;
list = list.map((val) => {
const spl = val.split(" ").map(Number);
const max = Math.max(...spl);
const min = Math.min(...spl);
if (max > maxH) {
maxH = max;
}
if (min < minH) {
minH = min;
}
return spl;
});
class Char { // 캐릭터 객체 짜기
constructor(store) { // store: 가지고 있는 흙 블록
this.inven = store; // 인벤토리에 넣어준다.
this.playTime = 0; // playTime은 0초로 초기화
}
PutInven(curH, toH) { // 인벤에 넣기 액션
// from 현재 높이 to 목표 높이
let diff = curH - toH;
this.inven += diff;
this.playTime += 2 * diff;
}
takeOutInven(curH, toH) { //인벤에서 꺼내기 액션
let diff = toH - curH;
this.inven -= diff;
this.playTime += diff;
}
getPlayTime() { // 현재 플레이타임을 얻기
return this.playTime;
}
getInven() { // 현재 인벤토리의 흙 블록 갯수 얻기
return this.inven;
}
}
for (let tarH = maxH; tarH >= minH; tarH--) {
const char = new Char(B);
// 2차원 배열로 순회
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
let curBlockH = list[i][j];
if (curBlockH === tarH) {
continue;
} else if (curBlockH > tarH) {
// 현재블록높이가 타겟보다 크면
char.PutInven(curBlockH, tarH);
} else if (curBlockH < tarH) {
// 현재블록높이가 타겟보다 작으면
char.takeOutInven(curBlockH, tarH);
}
}
}
const thisTime = char.getPlayTime();
const thisInven = char.getInven();
if (thisInven < 0) continue;
if (minTime === null) {
minTime = thisTime;
resH = tarH;
} else if (minTime > thisTime) {
minTime = thisTime;
resH = tarH;
}
}
console.log(minTime + " " + resH);
지금 보니 가장 바깥 for문에 '2차원 배열 순회하는 코드'와 '시간 계산 코드'를 다 넣어놓았는데,
이것도 함수화하여 모듈화하는게 좋았겠다.
옛날에 푼 문제인데 다시 보니 고칠 점이 보인다.