6209번: 제자리 멀리뛰기
첫 번째 줄에는 갇힌 돌섬으로부터 탈출구까지의 거리 d(1 ≤ d ≤ 1,000,000,000), 작은 돌섬의 수 n(0 ≤ n ≤ 50,000), 제거할 수 있는 작은 돌섬의 수 m (0 ≤ m ≤ n)이 공백으로 구분되어 주어진다. 두
www.acmicpc.net
소요 시간: 32분
메모리: 25308KB
시간: 272ms
🔥 문제
돌섬과 탈출구 사이에는 총 n개의 작은 돌섬이 있다. n개의 작은 돌섬들 중 m개를 제거할때, 학생들이 각 돌섬을 점프한 최솟값을 최대한 크게 하려고 한다. 학생들은 탈출 시 n-m개의 모든 돌섬을 밟으면서 탈출해야 한다.
학생들이 갇힌 돌섬으로부터 탈출구까지의 거리 d가 주어지고, 각 n개의 작은 돌섬의 위치(갇힌 돌섬으로 부터의 거리)가 주어지며, 제거할 수 있는 작은 돌섬의 수 m이 주어질 때, m개를 제거한 후 학생들이 점프하는 최소거리의 최댓값을 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에는 갇힌 돌섬으로부터 탈출구까지의 거리 d(1 ≤ d ≤ 1,000,000,000), 작은 돌섬의 수 n(0 ≤ n ≤ 50,000), 제거할 수 있는 작은 돌섬의 수 m (0 ≤ m ≤ n)이 공백으로 구분되어 주어진다.
두 번째 줄부터 n줄에 걸쳐서 갇힌섬으로부터 각 작은 돌섬이 얼마나 떨어져 있는지를 나타내는 하나의 정수가 한 줄에 하나씩 주어진다. (단, 두 돌섬은 같은 위치에 있을 수 없다.)
출력
m개의 작은섬을 제거한 뒤 학생들이 점프할 수 있는 최소거리의 최댓값을 출력한다.
🍀 풀이
배열`rockIslands`에 작은 돌섬들을 입력받고, 돌섬위치인 `0`을 추가한 후 오름차순 정렬하였다.
'돌섬 사이의 최소거리'를 기준으로 이분탐색 실행했다. `[0, d]`를 초기 범위로 이분탐색을 진행한다.
rockIslands[i] - rockIslands[j] (j < i)
1. `mid`보다 작다면 `i`돌섬을 제거한다.
2. `mid`보다 크거나 같다면, 조건에 만족하므로 학생들은 `j`돌섬으로 점프한다.(= `j`를 `i`로 갱신한다.)
그리고 제거한 돌섬이 `m`보다 많은지, 적은지에 따라 다음 이분탐색의 범위를 정한다.
1. `rockIslands`에 `0`을 넣고 이후는 돌섬의 위치를 저장하고, 입력을 다 받으면 오름차순 정렬한다.
2. `start`는 출발지점인 `0`, `end`는 도착지점인 `d`로 초기화시킨 후 이분탐색을 진행한다.
1. `pt`는 학생들이 현재 위치해있는 돌섬의 인덱스를 저장하고(초기값=0), `count`는 제거하는 돌섬의 개수를 저장한다.
2. `i` 첫번째 돌섬부터 순차적으로 탐색하며 제거할 돌섬을 찾는다.
1. `pt`번째 돌섬에서 `i`번째 돌섬으로 가는 거리가 `mid`보다 크거나 같은 경우 `mid`가 점프하는 최소거리의 최댓값이 될 수 있으므로 학생들을 점프시킨다. `pt`값을 `i`로 갱신한다.
2. `pt`번째 돌섬에서 `i`번째 돌섬으로 가는 거리가 `mid`보다 작은 경우 `mid`가 점프하는 최소거리의 최댓값이 될 수 없으므로 거리를 늘리기 위해 돌섬을 제거한다. `count`값을 1 올린다.
3. `count`가 `M`보다 크다면 제거해야할 돌섬 수보다 많이 제거한 것이므로 거리의 폭을 줄인다. `end`에 `mid-1`을 저장한다.
4. `count`가 `M`보다 작거나 같다면 돌섬을 조건에 맞게 잘 제거한 것이므로 `answer`에 `mid`를 저장한다. 그리고 `start`에 `mid+1`을 저장한다.
3. `answer`를 출력한다.
💻 전체 코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int D = Integer.parseInt(st.nextToken());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[] rockIslands = new int[N + 1];
for (int i = 1; i <= N; i++)
rockIslands[i] = Integer.parseInt(br.readLine());
Arrays.sort(rockIslands);
int start = 0;
int end = D;
int answer = 0;
while (start <= end) {
int mid = (start + end) / 2;
int pt = 0, count = 0;
for (int i = 1; i <= N; i++) {
if (mid <= rockIslands[i] - rockIslands[pt]) {
pt = i;
} else {
count++;
}
}
if (count > M) {
end = mid - 1;
} else {
answer = mid;
start = mid + 1;
}
}
System.out.println(answer);
}
}
💫 리뷰
작은 돌섬이 정렬된다는 조건이 없었는데, 내가 혼자 그렇게 생각했다...ㅜ
앞으로 지레짐작하지 않기..!
'algorithm' 카테고리의 다른 글
| [BOJ] 백준 17244번 아맞다우산 (Java) (2) | 2024.05.02 |
|---|---|
| [BOJ] 백준 1062번 가르침 (Java) (0) | 2024.04.28 |
| [BOJ] 백준 11578번 팀원 모집 (Java) (0) | 2024.04.26 |
| [BOJ] 백준 17951번 흩날리는 시험지 속에서 내 평점이 느껴진거야 (Java) (1) | 2024.04.24 |
| [BOJ] 백준 3020번 개똥벌레 (Java) (0) | 2024.04.23 |







