PS❯BOJ2021-11-013 min read
[BOJ 1461] 도서관 - Java (그리디 정렬 & 양수/음수 분할 탐색)
음수 좌표와 양수 좌표를 분리하여 절대값이 큰 책부터 $M$권씩 묶어 왕복하고, 가장 멀리 있는 책은 돌아오지 않는 편도로 처리하여 이동 걸음을 최소화
#BOJ#그리디#정렬#Java
1. 문제 개요 및 조건 분석
| 항목 | 내용 |
|---|---|
| 문제 이름 | 도서관 (백준 1461번 / 골드 4) |
| 플랫폼 / 난이도 | 백준 (골드 4, 1461번) |
| 문제 링크 | 백준 1461번 |
| 제한 사항 | 시간 제한 2초, 메모리 제한 128MB |
| 입력 조건 | 책의 개수 $N \le 50$, 한 번에 들 수 있는 책의 개수 $M \le 50$, 책의 원래 위치 좌표 $X_i \in [-10,000, 10,000]$ |
| 핵심 규칙 | 0에서 출발하여 모든 책을 원래 위치에 두고 다시 0으로 돌아오지 않아도 됨. 최소 이동 걸음 수 계산 |
2. 접근 아이디어: 음수/양수 분할 & 가장 먼 곳 편도 처리
최적 이동 전략
- 음수와 양수의 독립 처리:
- 음수 책과 양수 책을 한 번에 들고 가면 원점을 왕복해야 하므로 동선이 낭비됩니다. 따라서 음수 좌표와 양수 좌표를 완전히 분리합니다.
- 절대값이 큰 책부터 $M$권씩 묶기:
- 가장 먼 곳에 갈 때 다른 책들을 함께 가져다 놓는 것이 이득입니다. 따라서 절대값이 큰 순서대로 $M$권씩 묶어 왕복 거리($\times 2$)를 누적합니다.
- 마지막 편도 할인:
- 모든 책을 제자리에 둔 뒤에는 원점으로 돌아올 필요가 없습니다.
- 따라서 **전체 책 중 원점에서 가장 멀리 떨어진 책(절대값 최댓값)**을 가장 마지막에 방문하여, 그 거리만큼은 돌아오는 걸음($\text{maxDist}$)을 빼줍니다.
3. Java 풀이 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
List<Integer> positive = new ArrayList<>();
List<Integer> negative = new ArrayList<>();
st = new StringTokenizer(br.readLine());
int maxDist = 0;
for (int i = 0; i < n; i++) {
int pos = Integer.parseInt(st.nextToken());
maxDist = Math.max(maxDist, Math.abs(pos));
if (pos > 0) {
positive.add(pos);
} else {
negative.add(-pos); // 양수로 변환하여 저장
}
}
// 절대값 큰 순서(내림차순) 정렬
positive.sort(Collections.reverseOrder());
negative.sort(Collections.reverseOrder());
int totalSteps = 0;
// 양수 방향 처리
for (int i = 0; i < positive.size(); i += m) {
totalSteps += positive.get(i) * 2;
}
// 음수 방향 처리
for (int i = 0; i < negative.size(); i += m) {
totalSteps += negative.get(i) * 2;
}
// 가장 먼 곳은 돌아오지 않으므로 편도 1회분 차감
totalSteps -= maxDist;
System.out.println(totalSteps);
}
}
4. 복잡도 분석
- 시간 복잡도: $O(N \log N)$ — 좌표 정렬 시간. $N \le 50$으로 수 밀리초 내 즉시 완료.
- 공간 복잡도: $O(N)$ — 양수 및 음수 리스트.
5. 채점 결과 및 통과 인증

← PREVIOUS LOG
[BOJ 11400] 단절선 - Java (DFS Spanning Tree & Tarjan 알고리즘)
NEXT LOG →[BOJ 1781] 컵라면 - Java (그리디 & 최소 힙 PriorityQueue)
COMMENTS // GITHUB DISCUSSIONS (GISCUS)