[오늘의 문제] 승준이의 효율적인 커밋 관리

shlim55·2025년 3월 21일

코딩테스트

목록 보기
8/223

출처: 항해99 자체 제작

승준이는 N개의 작업을 M일 안에 모두 커밋해야 합니다. 각 작업은 변경된 코드 라인 수를 가지고 있으며, 작업 순서는 변경할 수 없습니다. 하루에 처리할 수 있는 최대 코드 라인 수를 최소화하면서 M일 안에 모든 작업을 커밋하려고 합니다. 하루 최대 처리 가능한 코드 라인 수의 최솟값을 구하는 프로그램을 작성하세요.

입력 형식
첫 번째 줄에 세 개의 정수 N, M이 주어집니다.

N: 작업 기록 개수 (1 ≤ N ≤ 100,000)

M: 작업을 완료해야 하는 일수 (1 ≤ M ≤ N)

둘째 줄에 N개의 정수 L이 주어집니다.

각 정수 L는 변경된 코드 라인의 수를 나타냅니다. (1 ≤ L ≤ 10,000)

출력 형식
M일 동안 모든 작업을 처리하기 위한 하루 최대 처리 가능한 코드 라인 수의 최솟값을 출력합니다.

제약 조건
하루 동안 작업을 나눌 때, 연속된 작업만 같은 날에 포함할 수 있습니다.

모든 작업은 순서대로 커밋되어야 합니다.

모든 작업은 M일 안에 완료되어야 합니다.

힌트
특정 값으로 M일 안에 모든 작업을 처리할 수 있는지 확인하는 것이 가능합니다.

이분 탐색을 통해 가능한 값들 중 최솟값을 찾을 수 있습니다.

예제 입력 1
7 4
2 2 2 2 2 2 2
예제 출력 1
4
예제 입력 2
8 3
10 5 8 2 6 7 2 5
예제 출력 2
16

import java.util.;
import java.io.
;

public class Main {
public static boolean isPossible(int m, int[] work, int maxPerDay) {
// 현재 최대 라인수로 m일 안에 모든 작업을 처리할 수 있는지 확인하는 함수
int days = 1;
int currentSum = 0;

    for (int lines : work) {
        // 단일 작업이 하루 최대 작업량보다 큰 경우
        if (lines > maxPerDay) {
            return false;
        }

        // 현재 일에 더 작업을 추가할 수 없는 경우
        if (currentSum + lines > maxPerDay) {
            days++;
            currentSum = lines;
        } else {
            currentSum += lines;
        }
    }

    return days <= m;
}

public static int minLinesPerDay(int n, int m, int[] work) {
    // 이분 탐색을 통해 가능한 최소의 하루 최대 라인 수를 찾는 함수
    int left = Arrays.stream(work).max().getAsInt();  // 하루 최소 필요 라인 수
    int right = Arrays.stream(work).sum();  // 하루 최대 가능 라인 수
    int answer = right;

    while (left <= right) {
        int mid = ____;  // 중간값 계산

        // mid 값으로 m일 안에 처리 가능한지 확인
        if (____) {
            answer = Math.min(answer, mid);  // 현재값이 더 작다면 정답 갱신
            right = ____;  // 더 작은 값 탐색
        } else {
            left = mid + 1;  // 더 큰 값 탐색
        }
    }

    return answer;
}

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());

    int[] work = new int[N];
    st = new StringTokenizer(br.readLine());
    for (int i = 0; i < N; i++) {
        work[i] = Integer.parseInt(st.nextToken());
    }

    System.out.println(minLinesPerDay(N, M, work));
}

}

빈칸1: O
정답: (left + right) / 2
해설: 이분 탐색에서 중간값을 구할 때는 시작값(left)과 끝값(right)의 합을 2로 나누어야 합니다. 이때 자바에서는 정수 나눗셈(/)을 사용하여 하루에 처리 가능한 코드 라인 수의 중간값을 구합니다.

빈칸2: O
정답: isPossible(m, work, mid)
해설: 이분 탐색의 각 단계에서 중간값(mid)으로 M일 안에 모든 작업을 처리할 수 있는지 확인해야 합니다. 이를 위해 isPossible 함수에 현재 중간값(mid)을 전달하여 가능 여부를 판단합니다.

빈칸3: O
정답: mid - 1
해설: 현재 중간값으로 M일 안에 처리가 가능한 경우, 더 작은 값도 가능한지 확인하기 위해 오른쪽 경계를 mid - 1로 줄입니다.

이번에는 세문제 다 맞췄다.
문제가 쉬운건지 실력이 늘은건지는 모르겠다.

profile
Normal Programmer

0개의 댓글