Algorithm

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ | 체윑볡, 그리디 μ•Œκ³ λ¦¬μ¦˜

osean 2020. 12. 12. 02:22

문제

 

μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅ - 체윑볡

μ μ‹¬μ‹œκ°„μ— 도둑이 λ“€μ–΄, 일뢀 학생이 μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν–ˆμŠ΅λ‹ˆλ‹€. λ‹€ν–‰νžˆ μ—¬λ²Œ 체윑볡이 μžˆλŠ” 학생이 μ΄λ“€μ—κ²Œ μ²΄μœ‘λ³΅μ„ 빌렀주렀 ν•©λ‹ˆλ‹€. ν•™μƒλ“€μ˜ λ²ˆν˜ΈλŠ” 체격 순으둜 맀겨져 μžˆμ–΄, λ°”λ‘œ μ•žλ²ˆ

programmers.co.kr

문제 μ„€λͺ…

μ μ‹¬μ‹œκ°„μ— 도둑이 λ“€μ–΄, 일뢀 학생이 μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν–ˆμŠ΅λ‹ˆλ‹€. λ‹€ν–‰νžˆ μ—¬λ²Œ 체윑볡이 μžˆλŠ” 학생이 μ΄λ“€μ—κ²Œ μ²΄μœ‘λ³΅μ„ 빌렀주렀 ν•©λ‹ˆλ‹€. ν•™μƒλ“€μ˜ λ²ˆν˜ΈλŠ” 체격 순으둜 맀겨져 μžˆμ–΄, λ°”λ‘œ μ•žλ²ˆν˜Έμ˜ ν•™μƒμ΄λ‚˜ λ°”λ‘œ λ’·λ²ˆν˜Έμ˜ ν•™μƒμ—κ²Œλ§Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 4번 학생은 3번 ν•™μƒμ΄λ‚˜ 5번 ν•™μƒμ—κ²Œλ§Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€. 체윑볡이 μ—†μœΌλ©΄ μˆ˜μ—…μ„ 듀을 수 μ—†κΈ° λ•Œλ¬Έμ— μ²΄μœ‘λ³΅μ„ 적절히 빌렀 μ΅œλŒ€ν•œ λ§Žμ€ 학생이 μ²΄μœ‘μˆ˜μ—…μ„ λ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€.

전체 ν•™μƒμ˜ 수 n, μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν•œ ν•™μƒλ“€μ˜ λ²ˆν˜Έκ°€ λ‹΄κΈ΄ λ°°μ—΄ lost, μ—¬λ²Œμ˜ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ ν•™μƒλ“€μ˜ λ²ˆν˜Έκ°€ λ‹΄κΈ΄ λ°°μ—΄ reserveκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, μ²΄μœ‘μˆ˜μ—…μ„ 듀을 수 μžˆλŠ” ν•™μƒμ˜ μ΅œλŒ“κ°’μ„ return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μž‘μ„±ν•΄μ£Όμ„Έμš”.

μ œν•œμ‚¬ν•­

  • 전체 ν•™μƒμ˜ μˆ˜λŠ” 2λͺ… 이상 30λͺ… μ΄ν•˜μž…λ‹ˆλ‹€.
  • μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν•œ ν•™μƒμ˜ μˆ˜λŠ” 1λͺ… 이상 nλͺ… μ΄ν•˜μ΄κ³  μ€‘λ³΅λ˜λŠ” λ²ˆν˜ΈλŠ” μ—†μŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œμ˜ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ ν•™μƒμ˜ μˆ˜λŠ” 1λͺ… 이상 nλͺ… μ΄ν•˜μ΄κ³  μ€‘λ³΅λ˜λŠ” λ²ˆν˜ΈλŠ” μ—†μŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œ 체윑볡이 μžˆλŠ” ν•™μƒλ§Œ λ‹€λ₯Έ ν•™μƒμ—κ²Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ 학생이 μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν–ˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λ•Œ 이 학생은 μ²΄μœ‘λ³΅μ„ ν•˜λ‚˜λ§Œ λ„λ‚œλ‹Ήν–ˆλ‹€κ³  κ°€μ •ν•˜λ©°, 남은 체윑볡이 ν•˜λ‚˜μ΄κΈ°μ— λ‹€λ₯Έ ν•™μƒμ—κ²ŒλŠ” μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μ—†μŠ΅λ‹ˆλ‹€.
n lost reserve return
5 [2,4] [1,3,5] 5
5 [2,4] [3] 4
3 [3] [1] 2

풀이

μ„€λͺ…

  • ν•΄λ‹Ή λ¬Έμ œμ—μ„œ λ†“μΉ˜κΈ° μ‰¬μš΄ 점은 lost λ°°μ—΄κ³Ό reserve 배열에 μ€‘λ³΅λœ 데이터가 있으면 μ€‘λ³΅λœ λ°μ΄ν„°λŠ” μ—¬λΆ„μ˜ μ²΄μœ‘λ³΅μ„ μžμ‹ μ΄ μž…λŠ”λ‹€λŠ” 것이닀.
  • λ¨Όμ € ν•΄λ‹Ή 문제λ₯Ό ν’€κΈ° μœ„ν•΄ κ·œμΉ™μ„ μ„€μ •ν–ˆλ‹€.
    • μ²΄μœ‘λ³΅μ„ λ„λ‚œ λ‹Ήν•œ μ‚¬λžŒ(lost) → -1
    • μ—¬λΆ„μ˜ μ²΄μœ‘λ³΅μ„ 가지고 μžˆλŠ” μ‚¬λžŒ(reserve) → 1
    • μžμ‹ μ˜ 체윑볡만 가지고 μžˆλŠ” μ‚¬λžŒ(두 배열에 μ†ν•˜μ§€ μ•Šμ€ 데이터) → 0

μœ„μ˜ κ·œμΉ™μ„ λ°”νƒ•μœΌλ‘œ students 배열을 λ§Œλ“€κ³ , ν•΄λ‹Ή 배열을 lost와 reserve λ°°μ—΄ 만큼 λ°˜λ³΅ν•œλ‹€.

  • lost에 μ†ν•˜λŠ” 학생일 경우 → ν•΄λ‹Ή 인덱슀의 데이터 -1
  • reserve에 μ†ν•˜λŠ” 학생일 경우 → ν•΄λ‹Ή 인덱슀의 데이터 +1

ν•΄λ‹Ή 과정을 마치고 λ‚˜λ©΄ students 배열에 λˆ„κ°€ μ—†λŠ”μ§€, 여뢄을 가지고 μžˆλŠ”μ§€ νŒŒμ•…ν•  수 μžˆμœΌλ©΄μ„œ lost와 reserve 배열에 μ€‘λ³΅λ˜λŠ” λ°μ΄ν„°λŠ” 0으둜 λ§Œλ“€μ–΄ ν•΄λ‹Ή 학생이 μˆ˜μ—…μ„ 듀을 수 μžˆλ„λ‘ λ§Œλ“€ 수 μžˆλ‹€.

λ‚˜μ˜ 경우 μ΄μ „μ˜ 학생이 μ•„λ‹Œ 이후 학생뢀터 λΉŒλ €μ€„ 수 μžˆλŠ”μ§€ ν™•μΈν–ˆλŠ”λ°, 11번 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ—μ„œ μ‹€νŒ¨ν–ˆμ—ˆλ‹€.
ν•΄λ‹Ή μ‹€νŒ¨λŠ” lost 배열에 {1,3,5}, reserve 배열에 {2,4,5}의 데이터가 μ‘΄μž¬ν•œλ‹€κ³  κ°€μ •ν–ˆμ„ λ•Œ, λ‚˜μ˜ κ²½μš°μ—μ„œλŠ” 2번 학생이 3번 ν•™μƒμ—κ²Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ£Όκ²Œλ˜λ©΄μ„œ μˆ˜μ—…μ„ 듀을 수 μžˆλŠ” ν•™μƒμˆ˜κ°€ 4λͺ…μœΌλ‘œ μ΅œλŒ€ 5λͺ…인 κΈ°λŒ€κ°’κ³Ό λ‹€λ₯΄λ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ— μ΄ν›„μ˜ 학생뢀터가 μ•„λ‹Œ μ΄μ „μ˜ 학생뢀터 ν™•μΈν•œλ‹€λ©΄ 11번 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό κ°€λΏνžˆ! 톡과할 수 μžˆλ‹€. λ‹€λ§Œ, λ‚˜μ˜ μ½”λ“œκ°€ 가독성도 μ’‹μ§€μ•Šκ³ , κ°„κ²°ν•˜μ§€λ„ μ•Šλ‹€. λ‹€λ₯Έ λΆ„λ“€μ˜ μ½”λ“œλ₯Ό λ³΄λ©΄μ„œ 더 μ–΄μΈν•œ μ½”λ“œλ‘œ 진화할 수 μžˆλ„λ‘ 곡뢀해야겠닀!

μ½”λ“œ

package μ‹¬μ„±ν—Œ.μ•Œκ³ λ¦¬μ¦˜_6μ£Όμ°¨;

public class 체윑볡_ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€_그리디 {
    public static void main(String[] args) {
        int n = 5;
        int[] lost = { 2, 4 };
        int[] reserve = { 3 };
        int result = solution(n, lost, reserve);

        System.out.println("\n" + result);
    }

    public static int solution(int n, int[] lost, int[] reserve) {
        // ν•™μƒμˆ˜λ§ŒνΌ λ°°μ—΄ κ΅¬ν˜„
        int[] students = new int[n];
        // reserve 배열은 μ—¬λΆ„μ˜ μ²΄μœ‘λ³΅μ„ 가지고 μžˆλŠ” 학생이닀.
        // students λ°°μ—΄μ˜ ν•΄λ‹Ή ν•™μƒμ˜ 체윑볡 + 1
        for (int idx : reserve) {
            students[idx - 1]++;
        }

        // lost 배열은 μ²΄μœ‘λ³΅μ„ λ„λ‚œ λ‹Ήν•œ 학생이닀.
        // students λ°°μ—΄μ˜ ν•΄λ‹Ή ν•™μƒμ˜ 체윑볡 - 1
        for (int idx : lost) {
            students[idx - 1]--;
        }

        // ν•™μƒμˆ˜ 만큼 λ°˜λ³΅ν•œλ‹€.
        for (int i = 0; i < students.length; i++) {
            int p = i + 1; // ν˜„μž¬ μœ„μΉ˜μ˜ + 1
            int m = i - 1; // ν˜„μž¬ μœ„μΉ˜μ˜ - 1
            // ν˜„μž¬ 학생이 여뢄을 가지고 μžˆλ‹€λ©΄
            if (students[i] == 1) {
                // ν˜„μž¬ 학생 μ΄μ „μ˜ 학생뢀터 확인
                if (m >= 0) {
                    if (students[m] == -1) {
                        students[i] = 0;
                        students[m] = 0;
                    }
                }
                // ν˜„μž¬ 학생 λ‹€μŒμ˜ 학생 확인
                if (p < students.length) {
                    if (students[p] == -1 && students[i] != 0) {
                        students[i] = 0;
                        students[p] = 0;
                    }
                }
            }
        }

        // μ²΄μœ‘λ³΅μ„ μž…κ³  μˆ˜μ—…μ— μ°Έμ—¬ν•  수 μžˆλŠ” ν•™μƒμ˜ 수
        int cnt = 0;
        for (int a : students) {
            System.out.print(a + " ");
            if (a > -1)
                cnt++;
        }
        return cnt;
    }
}