λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
ProgramSolve/Baekjoon

[BOJ] 2512번 - μ˜ˆμ‚° (Java)

by SooooooooS 2024. 1. 15.
728x90

πŸ› οΈ 문제 πŸ› οΈ


πŸ—’οΈ μ„€λͺ… πŸ—’οΈ

이 문제λ₯Ό 처음 봀을 λ•Œ λ‹Ήμ—°νžˆ μ΄λΆ„νƒμƒ‰μœΌλ‘œ ν’€μ–΄μ•Ό κ² λ‹€κ³  μƒκ°ν–ˆλ‹€.

ꡬ해야할 μƒν•œμ•‘μ„ [0 ~ μš”μ²­ν•  κΈˆμ•‘ 쀑 κ°€μž₯ 큰 κ°’] κ΅¬κ°„μ—μ„œ 이뢄탐색을 ν•œλ‹€.

 

μ•„λž˜μ˜ μ½”λ“œλŠ” 이λ₯Ό κ΅¬ν˜„ν•œ 것이닀.

μ΄λ•Œ solve(mid) λŠ” λ°°μ •λœ μ˜ˆμ‚°μ˜ 합을 λ°˜ν™˜ν•œλ‹€.

이λ₯Ό κΈ°μ€€μœΌλ‘œ start와 endλ₯Ό λ³€κ²½ν•΄κ°€λ©° μ΅œλŒ€ μƒν•œμ•‘μ„ μ°ΎλŠ”λ‹€.

int start = 0;
int end = max;
while(start <= end) {
    int mid = (start + end) / 2;
    if(solve(mid) > m) {
        end = mid - 1;
    }
    else {
        start = mid + 1;   
    }
}
bw.write(end + "");

 

ν•˜μ§€λ§Œ λ‘λ²ˆμ§Έ 방법이 μƒκ°λ‚˜μ„œ 이 글을 μž‘μ„±ν•΄λ³Έλ‹€.

일반적으둜 κ³΅ν‰ν•˜κ²Œ 받을 수 μžˆλŠ” μƒν•œμ•‘ = 총 μ˜ˆμ‚° / μ§€λ°©μ˜ 수 = m / n
λ§Œμ•½μ— 총 μ˜ˆμ‚°μ΄ μš”μ²­ν•œ μ˜ˆμ‚°λ“€μ˜ 합보닀 크면
    → μš”μ²­ν•œ μ˜ˆμ‚° 쀑 μ΅œλŒ“κ°’λ§ŒνΌ μƒν•œμ•‘μ„ μ„€μ •ν•˜λ©΄ λœλ‹€.
총 μ˜ˆμ‚°μ΄ μš”μ²­ν•œ μ˜ˆμ‚°λ“€μ˜ 합보닀 μž‘μœΌλ©΄
    → κ³΅ν‰ν•˜κ²Œ 받을 수 μžˆλŠ” μƒν•œμ•‘μ—μ„œ 1μ”© μ¦κ°€ν•˜λ©° λ°°μ •λœ μ˜ˆμ‚°μ„ 계산해본닀.
    → λ°°μ •λœ μ˜ˆμ‚°μ΄ 총 μ˜ˆμ‚°λ³΄λ‹€ 컀지면 λ©ˆμΆ˜λ‹€.

 

이λ₯Ό μ½”λ“œλ‘œ κ΅¬ν˜„ν•˜λ©΄ μ•„λž˜μ™€ κ°™λ‹€.

if(sum <= m) {
    bw.write(max + "");
}
else {
    int current = m / n;
    while(true) {
        if(solve(current) > m) break;
        current++;
    }

    bw.write(current - 1 + "");
}

 

κ²°κ³Όλ₯Ό 비ꡐ해보면 이뢄탐색을 μ‚¬μš©ν•œ 방법이 νš¨μœ¨μ μ΄λ‹€.

이뢄탐색을 톡해 μ°Ύμ•„κ°€λŠ” 방법은 κ΅¬κ°„μ—μ„œ 쀑간값을 μ°Ύμ•„μ„œ νƒμƒ‰ν•˜λ―€λ‘œ 평균적인 μ‹œκ°„μ΄ 걸릴 것이닀.

ν•˜μ§€λ§Œ λ‚΄κ°€ λ‘λ²ˆμ§Έλ‘œ μƒκ°ν•œ 방식은 μ΅œμ†Ÿκ°’κ³Ό κ΅¬ν•˜κ³ μž ν•˜λŠ” κ°’μ˜ 차이가 μž‘μ„ λ•Œ 효율적일 것이닀.

4
1 1 1 500
500

μœ„μ™€ 같은 μž…λ ₯이 듀어왔을 경우 125λΆ€ν„° 1μ”© μ¦κ°€ν•˜λ©° 497을 κ΅¬ν•˜κ²Œ λœλ‹€.

이처럼 κ°’λ“€μ˜ μ°¨κ°€ 클 경우 μž…λ ₯이 κΈΈμ–΄μ§ˆμˆ˜λ‘ 였래 걸릴 수 μžˆλ‹€.

 

λͺ¨λ‘ λ§žλŠ” ν’€μ΄μ§€λ§Œ νš¨μœ¨μ„±μ„ 따지면 이뢄탐색이 μ ν•©ν•˜λ‹€.


πŸ€ 풀이 πŸ€

1️⃣ 이뢄탐색 풀이

import java.io.*;
import java.util.StringTokenizer;

public class Main {
    static int[] requests;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int n = Integer.parseInt(br.readLine());
        requests = new int[n];

        StringTokenizer st = new StringTokenizer(br.readLine());
        int max = 0;
        for(int i = 0; i < n; i++) {
            requests[i] = Integer.parseInt(st.nextToken());
            max = Math.max(max, requests[i]);
        }

        int m = Integer.parseInt(br.readLine());

        int start = 0;
        int end = max;
        while(start <= end) {
            int mid = (start + end) / 2;
            if(solve(mid) > m) {
                end = mid - 1;
            }
            else {
                start = mid + 1;   
            }
        }
        bw.write(end + "");
        bw.flush();
        bw.close();
    }

    static int solve(int current) {
        int answer = 0;
        for(int i = 0; i < requests.length; i++) {
            answer += current >= requests[i] ? requests[i] : current;
        }
        return answer;
    }
}

2️⃣ κ°€λŠ₯ν•œ μƒν•œμ•‘ 쀑 μ΅œμ†Œλ₯Ό 계산 ν›„ μ΅œλŒ“κ°’ κ΅¬ν•˜κΈ°

package Baekjoon;

import java.io.*;
import java.util.StringTokenizer;

public class BinarySearch2512 {
    static int[] requests;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int n = Integer.parseInt(br.readLine());
        requests = new int[n];

        StringTokenizer st = new StringTokenizer(br.readLine());
        int sum = 0;
        int max = 0;
        for(int i = 0; i < n; i++) {
            requests[i] = Integer.parseInt(st.nextToken());
            sum += requests[i];
            max = Math.max(max, requests[i]);
        }

        int m = Integer.parseInt(br.readLine());

        if(sum <= m) { //μš”μ²­ μ˜ˆμ‚°μ˜ 합이 전체 μ˜ˆμ‚°λ³΄λ‹€ μž‘μ„ 경우
            bw.write(max + ""); //κ°€μž₯ μš”μ²­μ΄ 큰 μ•‘μˆ˜μ— λ§žμΆ˜λ‹€.
        }
        else {
            int current = m / n; //κ³΅ν‰ν•˜κ²Œ λ‚˜λˆ΄μ„ κ²½μš°λΆ€ν„° 탐색
            while(true) {
                if(solve(current) > m) break;
                current++;
            }

            bw.write(current - 1 + "");
        }
        bw.flush();
        bw.close();
    }

    static int solve(int current) {
        int answer = 0;
        for(int i = 0; i < requests.length; i++) {
            answer += current >= requests[i] ? requests[i] : current;
        }
        return answer;
    }
}
728x90