λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
μ•Œκ³ λ¦¬μ¦˜

[Java] BOJ 2108 톡계학

by 🍊귀🍊 2024. 7. 22.

문제 

문제 링크 https://www.acmicpc.net/problem/2108

    • ν†΅κ³„ν•™μ—μ„œ N개의 수λ₯Ό λŒ€ν‘œν•˜λŠ” κΈ°λ³Έ ν†΅κ³„κ°’μ—λŠ” λ‹€μŒκ³Ό 같은 것듀이 μžˆλ‹€. 단, N은 ν™€μˆ˜λΌκ³  κ°€μ •ν•˜μž.
      1. μ‚°μˆ ν‰κ·  : N개의 μˆ˜λ“€μ˜ 합을 N으둜 λ‚˜λˆˆ κ°’
      2. 쀑앙값 : N개의 μˆ˜λ“€μ„ μ¦κ°€ν•˜λŠ” μˆœμ„œλ‘œ λ‚˜μ—΄ν–ˆμ„ 경우 κ·Έ 쀑앙에 μœ„μΉ˜ν•˜λŠ” κ°’
      3. μ΅œλΉˆκ°’ : N개의 μˆ˜λ“€ 쀑 κ°€μž₯ 많이 λ‚˜νƒ€λ‚˜λŠ” κ°’
      4. λ²”μœ„ : N개의 μˆ˜λ“€ 쀑 μ΅œλŒ“κ°’κ³Ό μ΅œμ†Ÿκ°’μ˜ 차이
    • N개의 μˆ˜κ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, λ„€ 가지 κΈ°λ³Έ 톡계값을 κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.
    • 첫째 쀄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진닀. 단, N은 ν™€μˆ˜μ΄λ‹€.
    • κ·Έ λ‹€μŒ N개의 μ€„μ—λŠ” μ •μˆ˜λ“€μ΄ 주어진닀. μž…λ ₯λ˜λŠ” μ •μˆ˜μ˜ μ ˆλŒ“κ°’μ€ 4,000을 λ„˜μ§€ μ•ŠλŠ”λ‹€.
    • 첫째 μ€„μ—λŠ” μ‚°μˆ ν‰κ· μ„ 좜λ ₯ν•œλ‹€. μ†Œμˆ˜μ  μ΄ν•˜ 첫째 μžλ¦¬μ—μ„œ λ°˜μ˜¬λ¦Όν•œ 값을 좜λ ₯ν•œλ‹€.
    • λ‘˜μ§Έ μ€„μ—λŠ” 쀑앙값을 좜λ ₯ν•œλ‹€.
    • μ…‹μ§Έ μ€„μ—λŠ” μ΅œλΉˆκ°’μ„ 좜λ ₯ν•œλ‹€. μ—¬λŸ¬ 개 μžˆμ„ λ•Œμ—λŠ” μ΅œλΉˆκ°’ 쀑 두 번째둜 μž‘μ€ 값을 좜λ ₯ν•œλ‹€.
    • λ„·μ§Έ μ€„μ—λŠ” λ²”μœ„λ₯Ό 좜λ ₯ν•œλ‹€.

아이디어

  • μ ˆλŒ“κ°’ 4000이 λ²”μœ„λΌκ³  ν–ˆμœΌλ―€λ‘œ 배열을 8001크기둜 λ§Œλ“€μ–΄μ„œ μž…λ ₯λ°›λŠ” μˆ«μžμ— 4000을 λ”ν•œ μœ„μΉ˜μ— +1을 ν–ˆλ‹€.
  • μž…λ ₯λ°›μœΌλ©΄μ„œ μ΅œμ†Ÿκ°’κ³Ό μ΅œλŒ“κ°’μ„ 갱신해쀬고, μ‚°μˆ ν‰κ· μ„ κ΅¬ν•˜κΈ° μœ„ν•œ 총합도 κ³„μ‚°ν–ˆλ‹€. 
  • μž…λ ₯을 λ‹€ 받은 ν›„, λ°°μ—΄ 크기만큼 λ°˜λ³΅λ¬Έμ„ λŒλ¦¬λ©΄μ„œ ν•΄λ‹Ή λ°°μ—΄μ˜ 값이 1이상이면 카운트 λ³€μˆ˜μ— +1을 ν•΄μ£Όκ³  ν•΄λ‹Ή μΉ΄μš΄νŠΈκ°€ (전체 μž…λ ₯받은 개수 / 2) + 1인지 ν™•μΈν•˜λ©° 쀑앙값을 μ°Ύμ•˜λ‹€. 
  • 그리고 λ°°μ—΄ 값에 따라 ν•΄λ‹Ή 배열값이 μ΅œλΉˆκ°’μ΄ 될 수 μžˆλŠ” μˆ˜λ³΄λ‹€ 더 크닀면 ν•΄λ‹Ή λ°°μ—΄ μœ„μΉ˜μ— ν•΄λ‹Ήν•˜λŠ” μˆ«μžκ°€ 졜빈 κ°’μ΄λ―€λ‘œ μ΅œλΉˆκ°’μ„ 갱신해쀬닀.
  • λ§Œμ•½ μ΅œλΉˆκ°’μ΄ μ—¬λŸ¬κ°œμΌ 경우, λ‘λ²ˆμ§Έλ‘œ μž‘μ€ 수λ₯Ό 좜λ ₯ν•΄μ•Όλ˜λ―€λ‘œ boolean λ³€μˆ˜λ₯Ό 톡해 λ§Œμ•½ μ΅œλΉˆκ°’μ˜ κ°œμˆ˜μ™€ ν•΄λ‹Ή λ³€μˆ˜μ˜ κ°œμˆ˜κ°€ λ˜‘κ°™κ³  boolean λ³€μˆ˜κ°€ false이면 λ‘λ²ˆμ§Έ μž‘μ€ μ΅œλΉˆκ°’μ΄λ―€λ‘œ μ΅œλΉˆκ°’μ„ κ°±μ‹ ν•΄μ£Όκ³  boolean값을 true둜 λ³€ν™˜ν•΄μ€€λ‹€.

κ²ͺ은 μ‹œν–‰μ°©μ˜€

  • λ§Žμ€ μ‹œν–‰μ°©μ˜€λ₯Ό κ²ͺμ—ˆλ‹€... μš°μ„  λ§Žμ΄λ„ ν‹€λ Έλ‹€... λΆ„λͺ… μ˜ˆμ œλŠ” λ‹€ 맞고 λ‹€λ₯Έ λ°˜λ‘€λ“€λ„ λ‹€ λ§žλŠ”λ° 자꾸 ν‹€λ Έλ‹€κ³  λ‚˜μ™”λ‹€...
  • λ°˜λ‘€λ₯Ό μ°Ύκ³  또 찾은 κ²°κ³Ό μ΅œλΉˆκ°’μ„ κ³„μ‚°ν•˜λŠ” κ³Όμ •μ—μ„œ λ¬Έμ œκ°€ 있음이 λ“œλŸ¬λ‚¬λ‹€...
  • μ΅œλΉˆκ°’μ΄ μ—¬λŸ¬κ°œμΌλ•Œ, λ‘λ²ˆμ§Έλ‘œ μž‘μ€ μ΅œλΉˆκ°’μ„ κ΅¬ν•˜κΈ° μœ„ν•΄ boolean λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ”λ°, λ§Œμ•½ μ΅œλΉˆκ°’μ΄ κ°±μ‹ λœλ‹€λ©΄(μ΅œλΉˆκ°’μ΄ μ—¬λŸ¬κ°œκ°€ λ˜λŠ” 경우 X, κ°œμˆ˜κ°€ 더 λ§Žμ•„μ„œ μƒˆλ‘­κ²Œ κ°±μ‹ λ λ•Œ) boolean λ³€μˆ˜λ„ λ‹€μ‹œ false둜 μ΄ˆκΈ°ν™”ν•΄μ€˜μ•ΌλλŠ”λ° κ·Έ μ΄ˆκΈ°ν™”λ₯Ό 해주지 μ•Šμ•„μ„œ ν‹€λ Έμ—ˆλ‹€....(λΆ„λ°œν•˜μž...)

'ν‹€λ ΈμŠ΅λ‹ˆλ‹€'의 μΆ•μ œ....
λ°˜λ‘€ 찾느라 λ„ˆλ¬΄λ„ˆλ¬΄ νž˜λ“€μ—ˆλ‹€....γ…œγ…œγ…œγ…œγ…œγ…œ

μ½”λ“œ

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

public class BOJ2108 {
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // μž…λ ₯λ°›λŠ” 숫자의 개수
        int N = Integer.parseInt(br.readLine());

        // 평균 계산할 λ³€μˆ˜
        double avg = 0;

        // μ΅œλŒ“κ°’, μ΅œμ†Ÿκ°’ 계산을 μœ„ν•œ λ³€μˆ˜
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;

        // 쀑앙값을 찾을 λ•Œ μ“°λŠ” λ³€μˆ˜
        int mid = 0;

        // μ΅œλΉˆκ°’μ„ 찾을 λ•Œ μ“°λŠ” λ³€μˆ˜
        int value = 0;

        // μ΅œλΉˆκ°’μ„ μ°ΎκΈ° μœ„ν•œ λ°°μ—΄
        int arr[] = new int[8001];

        // μ‚°μˆ ν‰κ·  κ²°κ³Όκ°’
        int result1 = 0;
        // 쀑앙값 κ²°κ³Όκ°’
        int result2 = 0;
        // μ΅œλΉˆκ°’ κ²°κ³Όκ°’
        int result3 = 0;
        // λ²”μœ„ κ²°κ³Όκ°’
        int result4 = 0;

        for(int i = 0; i < N; i++){
            int n = Integer.parseInt(br.readLine());

            // 평균 값을 κ³„μ‚°ν•˜κΈ° μœ„ν•΄ λ”ν•΄μ€Œ
            avg = avg + n;

            // λ°°μ—΄μ˜ ν•΄λ‹Ή κ°’ μœ„μΉ˜μ— + 1
            // μ ˆλŒ“κ°’ 4000이라고 ν–ˆμœΌλ―€λ‘œ λ§ˆμ΄λ„ˆμŠ€λ„ 올 수 μžˆμœΌλ‹ˆ +4000을 ν•΄μ€Œ
            arr[n + 4000] = arr[n + 4000] + 1;

            // μž…λ ₯λ“€μ–΄μ˜€λŠ” 값이 ν˜„μž¬ μ΅œμ†Ÿκ°’λ³΄λ‹€ μž‘λ‹€λ©΄ κ°±μ‹ 
            if(min > n){
                min = n;
            }

            // μž…λ ₯λ“€μ–΄μ˜€λŠ” 값이 ν˜„μž¬ μ΅œλŒ“κ°’λ³΄λ‹€ 크닀면 κ°±μ‹ 
            if(max < n){
                max = n;
            }
        }

        // λͺ‡κ°œμ§ΈμΈμ§€ μ„ΈκΈ°μœ„ν•œ λ³€μˆ˜
        int cnt = 0;

        // μ΅œλΉˆκ°’μ΄ 같을 경우, 제일 μž‘μ€ μˆ˜μΈμ§€ νŒλ³„ν•˜κΈ° μœ„ν•΄μ„œ
        boolean TF = false;

        // 쀑앙값과 μ΅œλΉˆκ°’μ„ μ°ΎκΈ° μœ„ν•œ 반볡문
        for(int i = 0; i < 8001; i++){
            // λ§Œμ•½ 1보닀 크닀면 μž…λ ₯이 λμ—ˆλ‹€λŠ” μ˜λ―Έλ―€λ‘œ
            // μž…λ ₯된 횟수만큼 카운트
            if(arr[i] >= 1){
                // μž…λ ₯된 횟수만큼 λ°˜λ³΅λ¬Έμ„ λŒλ©΄μ„œ
                for(int j = 0; j < arr[i]; j++){
                    // 1μ”© μΉ΄μš΄νŠΈμ— 더해주고
                    cnt = cnt + 1;

                    // λ§Œμ•½ μΉ΄μš΄νŠΈκ°€ 전체 개수λ₯Ό 2둜 λ‚˜λˆˆκ²ƒμ—μ„œ 1을 λ”ν•œ κ°’κ³Ό
                    // κ°™λ‹€λ©΄ μ€‘μ•™κ°’μ΄λ―€λ‘œ 쀑앙값 κ°±μ‹ 
                    // 처음 μ €μž₯ν• λ•Œ λ§ˆμ΄λ„ˆμŠ€λ₯Ό κ³ λ €ν•΄μ„œ + 4000을 ν•΄μ€¬μœΌλ―€λ‘œ -4000을 ν•΄μ€Œ
                    if(cnt == ((N / 2) + 1)){
                        mid = i - 4000;
                    }
                }

                // λ§Œμ•½ κΈ°μ‘΄ μ΅œλΉˆκ°’μ˜ κ°œμˆ˜λ³΄λ‹€ 더 κ°œμˆ˜κ°€ 크닀면
                if(value < arr[i]){
                    // μ΅œλΉˆκ°’μ˜ 개수λ₯Ό κ°±μ‹ ν•˜κ³ 
                    value = arr[i];

                    // ν•΄λ‹Ήν•˜λŠ” μ΅œλΉˆκ°’μ„ 결과값에 μ €μž₯
                    result3 = i - 4000;

                    // μ΅œλΉˆκ°’μ΄ κ°±μ‹ λμœΌλ―€λ‘œ
                    // TFλ₯Ό λ‹€μ‹œ μ΄ˆκΈ°ν™”
                    // μ΅œλΉˆκ°’μ΄ 될 수 μžˆλŠ” 개수λ₯Ό 가진 수 쀑 λ‹€μ‹œ κ°€μž₯ μž‘μ€ μˆ˜κ°€ λμœΌλ―€λ‘œ
                    TF = false;
                }
                // λ§Œμ•½ κΈ°μ‘΄ μ΅œλΉˆκ°’μ˜ κ°œμˆ˜μ™€ κ°œμˆ˜κ°€ κ°™λ‹€λ©΄
                else if(value == arr[i]){
                    // μ—¬λŸ¬κ°œμ˜ μ΅œλΉˆκ°’λ“€ 쀑 μ΅œμ†Ÿκ°’μΈμ§€ νŒλ‹¨ν•΄μ•Όν•¨
                    // λ§Œμ•½ λ³€μˆ˜κ°€ false라면 아직 첫번째 κ°’μ΄λΌλŠ” μ˜λ―Έλ―€λ‘œ
                    // ν˜„μž¬ 값이 λ‘λ²ˆμ§Έλ‘œ μž‘μ€ μˆ˜κ°€ 됨 λ”°λΌμ„œ TFλ₯Ό true둜 λ°”κΎΈκ³ 
                    // μ΅œλΉˆκ°’ κ°±μ‹ 
                    if(!TF){
                        // ν•΄λ‹Ήν•˜λŠ” μ΅œλΉˆκ°’μ„ 결과값에 μ €μž₯
                        result3 = i - 4000;

                        TF = true;
                    }
                }
            }

            // μž…λ ₯된 횟수만큼 λͺ¨λ“  숫자λ₯Ό μ°Ύμ•˜μœΌλ©΄ 반볡문 μ’…λ£Œ
            if(cnt == N){
                break;
            }
        }

        result1 = (int)Math.round(avg / N);
        result2 = mid;
        result4 = max - min;

        System.out.println(result1);
        System.out.println(result2);
        System.out.println(result3);
        System.out.println(result4);
    }
}



'μ•Œκ³ λ¦¬μ¦˜' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[Java] BOJ 1874 μŠ€νƒ μˆ˜μ—΄  (14) 2024.07.23
[Java] BOJ 1654 λžœμ„  자λ₯΄κΈ°  (10) 2024.07.22
[Java] BOJ 1966 ν”„λ¦°ν„° 큐  (0) 2024.07.21
[Java] BOJ 1929 μ†Œμˆ˜ κ΅¬ν•˜κΈ°  (0) 2024.07.21
[Java] BOJ 18110 solved.ac  (2) 2024.07.21