Notice
Recent Posts
Recent Comments
Link
algoqna
[BOJ 15732] 도토리 숨기기 본문
15732번: 도토리 숨기기
첫째 줄에 상자의 개수 N(1 ≤ N ≤ 1,000,000)과 규칙의 개수 K(1 ≤ K ≤ 10,000), 도토리의 개수 D(1 ≤ D ≤ 1,000,000,000)가 주어진다. 그 후 K개 줄에는 A, B, C(1 ≤ C ≤ A ≤ B ≤ N)가 주어지며 A번 상자부터
www.acmicpc.net
조건
- 상자의 개수 N(1 ≤ N ≤ 1,000,000)과 규칙의 개수 K(1 ≤ K ≤ 10,000), 도토리의 개수 D(1 ≤ D ≤ 1,000,000,000)
- K개 줄에는 A, B, C(1 ≤ C ≤ A ≤ B ≤ N)가 주어지며 A번 상자부터 B번 상자까지 C개 간격으로 도토리를 하나씩 넣는 규칙을 뜻한다. D는 모든 규칙으로 넣을 수 있는 도토리의 수보다 같거나 작다.
문제 재정의
- 도토리를 상자 앞에서부터 순차적으로 넣었을 때 “마지막” 도토리가 들어있는 **“상자의 번호”**를 찾는다.
- 상자의 개수가 1 ≤ N ≤ 1,000,000이기 때문에 최대 상자의 번호는 1,000,000
최악 계산
- 반복문으로 상자에 넣을 경우 A가 1이고 B가 N(1,000,000)인 경우만 입력으로 10000개가 들어왔다고 한다면, O(N * K) = 100억
- 이분 탐색을 고민
예외 조건
- D는 모든 규칙으로 넣을 수 있는 도토리의 수보다 같거나 작다.
- D의 최대는 10억, 누적 합이 10억 * K(10000) → long으로 처리해야 한다.
계산 로직 정의
- 상자의 번호를 1과 N 사이에서 이분 탐색
- mid가 상자의 번호가 되고, 상자의 번호까지 왔을 때
- 마지막 도토리보다 같거나 많이 줄 수 있다면 답의 후보이며 상자의 번호를 줄여보고
- 아니라면 상자의 번호를 늘린다.
- 도토리의 개수는 K개의 규칙에 대하여
- 각 규칙마다 상자의 시작 번호가 mid보다 크다면 continue
- 아니라면 mid와 규칙의 마지막 상자 번호의 대소를 비교해서 범위를 재설정
- 이후 계산
- O(KlogN)
package Baekjoon;
import java.io.*;
import java.util.*;
public class BOJ15732 {
static int N,K,D;
static int[][] rules;
public static void main(String[] args) throws IOException{
init();
System.out.println(binarySearch());
}
private static int binarySearch() {
int left = 1;
int right = N;
while (left <= right) {
int mid = (left + right) / 2;
long corns = cntOfCorns(mid);
if (corns >= D) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
return right + 1;
}
private static long cntOfCorns(int mid) {
long sum = 0;
int right = 0;
int res = 0;
for (int i = 0; i < K; i++) {
if (rules[i][0] > mid) continue;
right = Math.min(mid,rules[i][1]);
res = (right - rules[i][0]);
sum += res / rules[i][2] + 1;
}
return sum;
}
private static void init() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
N = Integer.parseInt(input[0]);
K = Integer.parseInt(input[1]);
D = Integer.parseInt(input[2]);
rules = new int[K][3];
for (int i = 0; i < K; i++) {
input = br.readLine().split(" ");
rules[i][0] = Integer.parseInt(input[0]);
rules[i][1] = Integer.parseInt(input[1]);
rules[i][2] = Integer.parseInt(input[2]);
}
Arrays.sort(rules,(o1,o2) -> { return Integer.compare(o1[0],o2[0]);});
}
}
Add : BOJ15732 도토리 숨기기 이분 탐색 풀이 · ssjjaa-algo/AlgoAndMySQL@317c649
ssjjaa-algo committed Nov 28, 2023
github.com
'프로그래밍 > 이분 탐색' 카테고리의 다른 글
[BOJ 2110] 공유기 설치 (0) | 2023.02.21 |
---|---|
[BOJ 14425] 문자열 집합 (2) | 2022.09.26 |
[BOJ 1654] 랜선 자르기 (0) | 2022.09.17 |
[BOJ 10816] 숫자 카드2 (0) | 2022.09.15 |
[BOJ 1920] 수 찾기 (0) | 2022.09.14 |