
도서관에서 모든 책을 제자리에 놓아야 한다.
한번에 M개의 책을 옮길 수 있고 모든 책은 현재 위치 0에 있다.
모든 책을 제자리에 두면 다시 0의 위치로 돌아올 필요 없다.
모든 책을 제자리에 두는 최소 거리를 구하여라.
최단 거리는 거리의 절댓값이 최대인 경우를 우선하여 갔다 온 후, 가장 먼 거리를 빼주면 될 것이다. (마지막의 경우 왕복을 한번만 하면 된다.)
그런데 이 문제의 경우 0을 기준으로 음수 양수가 존재하기 때문에 두 경우를 나누어서 계산해야 한다.
M개의 책을 옮길 수 있기 때문에 인덱스 += M 으로 거리를 계산.Dice 클래스
let fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
let [N, M] = input.shift().split(' ').map(Number);
let Books = input.shift().split(' ').map(Number);
// 0 기준 왼쪽. 즉 음수.
let Left = Books.filter(v => v < 0).sort((a, b) => {
return Math.abs(b) - Math.abs((a));
});
// 양수.
let Right = Books.filter(v => v > 0).sort((a, b) => {
return Math.abs(b) - Math.abs((a));
});
// 걸음수.
let Distance = 0;
// 최대 거리.
let max = 0;
// 반복문에서 사용할 인덱스 번호.
let leftIDX = 0;
while (Left.length > leftIDX) {
// 왕복 거리로 계산.
Distance += Math.abs(Left[leftIDX]) * 2;
// 최댓값 계산.
max = max < Math.abs(Left[leftIDX]) ? Math.abs(Left[leftIDX]) : max;
// 인덱스 값 증가.
leftIDX += M;
}
// 위와 동일.
let rightIDX = 0;
while (Right.length > rightIDX) {
Distance += Math.abs(Right[rightIDX]) * 2;
max = max < Math.abs(Right[rightIDX]) ? Math.abs(Right[rightIDX]) : max;
rightIDX += M;
}
// 전체 걸음수에서 마지막 걸음수는 빼준다.
console.log(Distance - max);
어떤 경우가 걸음수가 최소가 되는지 이해하는데 오래 걸렸던 문제였다.
막상 최소가 되는 경우를 알고나니 매우 쉽게 풀렸다.