λšœλΆ€λ‹ˆμ˜ Devlog

[BOJ] 2016.λ―ΈνŒ…μ£Όμ„ ν•˜κΈ°

by λšœλΆ€λ‹ˆ
 

2016번: λ―ΈνŒ… μ£Όμ„ ν•˜κΈ°

νƒœν˜„μ΄λŠ” λ„€ λͺ…μ˜ μΉœκ΅¬μ™€ 5λŒ€ 5 λ―ΈνŒ…μ— μ°Έμ—¬ν•˜κ²Œ λ˜μ—ˆλ‹€. λ―ΈνŒ… μžλ¦¬μ—μ„œ 각 μ‚¬λžŒμ˜ μ†Œκ°œκ°€ λλ‚˜κ³ , 각자의 짝을 μ •ν•  μ‹œκ°„μ΄ λ˜μ—ˆλŠ”λ°, νƒœν˜„μ΄κ°€ λ‹€μŒκ³Ό 같은 방법을 μ œμ•ˆν•˜μ˜€κ³ , λͺ¨λ‘ 이에 μ°¬μ„±

www.acmicpc.net

 

문제

λ―ΈνŒ… μžλ¦¬μ—μ„œ 각자의 짝을 μ •ν•˜λŠ” 방법은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  1. νƒœν˜„μ΄κ°€ 1번, λ‚˜λ¨Έμ§€ 남학생이 2-5번, 여학생이 6-10λ²ˆμž…λ‹ˆλ‹€.
  2. 각자 μƒλŒ€μ— λŒ€ν•œ μ„ ν˜Έλ„ μˆœμœ„λ₯Ό λ§€κ²¨μ„œ μ”λ‹ˆλ‹€.
    μ΄λ•Œ, 두 λͺ… μ΄μƒμ˜ μƒλŒ€μ—κ²Œ 같은 μ„ ν˜Έλ„λ₯Ό μ μš©ν•˜λ©΄ μ•ˆ 되고, 5λͺ… λͺ¨λ‘μ— λŒ€ν•œ μˆœμœ„λ₯Ό 맀겨야 ν•©λ‹ˆλ‹€.
  3. 6번 여학생뢀터 κ°€μž₯ μ’‹μ•„ν•˜λŠ” λ‚¨ν•™μƒμ—κ²Œ ν”„λŸ¬ν¬μ¦ˆλ₯Ό ν•˜λ©°, ν‡΄μž 맞으면 λ‹€μŒ μˆœμ„œμ˜ λ‚¨ν•™μƒμ—κ²Œ ν”„λŸ¬ν¬μ¦ˆλ₯Ό ν•©λ‹ˆλ‹€.
  4. 남학생은 ν˜„μž¬ 짝이 μ—†μœΌλ©΄ 무쑰건 ν”„λŸ¬ν¬μ¦ˆλ₯Ό λ°›μœΌλ©°,
    두 λͺ… 이상인 경우 더 μ„ ν˜Έν•˜λŠ” 여학생과 짝이 되고 λ‚˜λ¨Έμ§€ μ—¬ν•™μƒμ—κ²Œ ν‡΄μ§œλ₯Ό λ†“μŠ΅λ‹ˆλ‹€.
  5. ν‡΄μ§œ 받은 μ—¬ν•™μƒλ“€λ§Œ λ‹€μŒ λΌμš΄λ“œμ—μ„œ 짝짓기에 μ°Έμ—¬ν•©λ‹ˆλ‹€.

λͺ¨λ“  학생듀이 짝을 찾을 λ•ŒκΉŒμ§€ 이 과정을 λ°˜λ³΅ν•˜λ©° λ§ˆμ§€λ§‰μ— μ„œλ‘œμ˜ 짝이 μ΅œμ’… 짝이 λ©λ‹ˆλ‹€.

νƒœν˜„μ΄μ˜ μ„ ν˜Έλ„λŠ” 6 7 8 9 10 여학생 μˆœμ„œμž…λ‹ˆλ‹€.

ν•΄λ‹Ή μ„ ν˜Έλ„λ₯Ό μ λ‹Ήνžˆ λ°”κΏ” μ μ–΄μ„œ μ›λž˜ μ„ ν˜Έλ„ λ¦¬μŠ€νŠΈλ³΄λ‹€ 더 μ’‹μ•„ν•˜λŠ” 여학생과 짝이 될 수 μžˆλ‹€λ©΄ "YES", μ•„λ‹ˆλ©΄ "NO"λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.

 

풀이

  1. μž…λ ₯을 받을 λ•Œ μ„ ν˜Έλ„ 정보와 인덱슀λ₯Ό 기반으둜 점수λ₯Ό κΈ°μž¬ν•©λ‹ˆλ‹€. ( 0 ~ 4)
  2. νƒœν˜„μ΄μ˜ μ„ ν˜Έλ„λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. - μˆ˜μ—΄
  3. μœ„μ˜ λ°©λ²•λŒ€λ‘œ 짝을 μ •ν•©λ‹ˆλ‹€.
    • 이미 짝을 μ§€μ •ν•œ 여학생은 짝 선택을 ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
    • λ‚¨ν•™μƒμ˜ 짝이 μ—†λŠ” 경우, ν˜„μž¬ ν”„λŸ¬ν¬μ¦ˆν•œ 여학생과 짝이 λ©λ‹ˆλ‹€.
    • λ‚¨ν•™μƒμ˜ 짝이 μžˆλŠ” 경우, 짝과 ν˜„μž¬ μ—¬ν•™μƒμ˜ μ„ ν˜Έλ„λ₯Ό λΉ„κ΅ν•˜μ—¬, μ„ ν˜Έλ„κ°€ 더 높은 여학생과 짝이 λ©λ‹ˆλ‹€. (인덱슀 기반 점수 ν™œμš©)

 

ν’€μ΄λŠ” 생각보닀 더 μ‹¬ν”Œν•©λ‹ˆλ‹€. μ‹€μ œ μ½”λ“œλ₯Ό λ³΄μ—¬λ“œλ¦¬λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

import java.util.Scanner;

public class Main {
    static int[] myPreference = {6, 7, 8, 9, 10}; // νƒœν˜„μ˜ μ„ ν˜Έλ„
    static int[] outputPreference = new int[5];
    static int[] outputScores = new int[5];
    static int originPartner = 0;
    static int changePartner = 0;
    static int cnt = 0;

    // 짝 μ •ν•˜κΈ°
    public static void getPartner(int[][] preference, int[][] scores) {
        preference[1] = outputPreference;
        scores[1] = outputScores;
        int[] partners = new int[11]; // νŒŒνŠΈλ„ˆ 정보 기둝
        int[] findPartner = new int[5]; // μ—¬ν•™μƒμ˜ νŒŒνŠΈλ„ˆ 정보 기둝

        while (true) {
            boolean isContinue = false;
            for (int i = 6; i < 11; i++) {
                if (partners[i] != 0) continue; // 이미 짝을 μ§€μ •ν•œ 여학생은 짝 선택 X
                int idx = findPartner[i - 6]; // 여학생이 μ›ν•˜λŠ” 남학생 μš°μ„ μˆœμœ„ (인덱슀)
                findPartner[i - 6] = idx + 1; // 여학생이 λ‹€μ‹œ 짝을 찾을 λ•Œ μ‚¬μš©ν•  인덱슀

                int wantPartner = preference[i][idx]; // 여학생이 μ›ν•˜λŠ” 남학생
                if (partners[wantPartner] == 0) { // 아직 짝이 정해지지 μ•ŠμŒ
                    partners[wantPartner] = i;
                    partners[i] = wantPartner;
                } else {
                    isContinue = true;
                    int decidedPartner = partners[wantPartner]; // 남학생과 짝인 여학생 번호
                    
                    // μ„ ν˜Έλ„ 비ꡐ
                    if (scores[wantPartner][decidedPartner - 6] > scores[wantPartner][i - 6]) {
                        partners[wantPartner] = i;
                        partners[i] = wantPartner;
                        partners[decidedPartner] = 0; // 기쑴에 짝인 여학생은 μƒˆλ‘œ 지정해야 ν•œλ‹€.
                    }
                }
            }
            if (!isContinue) break;
        }

        if (cnt == 0) {
            originPartner = partners[1];
        } else {
            changePartner = partners[1];
        }

    }

    // νƒœν˜„μ˜ μ„ ν˜Έλ„ 생성
    public static void setPreference(int len, int[][] preference, int[][] scores, boolean[] used) {
        if (1 < cnt && originPartner > changePartner) {
            return;
        }

        if (len == 5) {
            // μ„ ν˜Έλ„ κ²°κ³Ό κ΅¬ν•˜κΈ°
            getPartner(preference, scores);
            cnt++;
            return;
        }

        for (int idx = 0; idx < 5; idx++) {
            if (!used[idx]) {
                used[idx] = true;
                int partner = myPreference[idx];
                outputPreference[len] = partner;
                outputScores[partner - 6] = len;
                setPreference(len + 1, preference, scores, used);
                used[idx] = false;
            }
        }
    }

    public static String solution(int[][] preferences, int[][] scores) {
        boolean[] used = new boolean[5]; // μ„ ν˜Έλ„ μ‚¬μš© 기둝
        cnt = 0;

        // μ„ ν˜Έλ„ 계산
        setPreference(0, preferences, scores, used);

        if (originPartner > changePartner) {
            return "YES";
        } else {
            return "NO";
        }
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int testcase = input.nextInt();
        int[][] preferences = new int[11][5];
        int[][] scores = new int[11][5]; // μš°μ„ μˆœμœ„μ— λ”°λ₯Έ 점수

        for (int tc = 0; tc < testcase; tc++) {
            // μ„ ν˜Έλ„ μž…λ ₯
            for (int i = 2; i < 11; i++) {
                for (int j = 0; j < 5; j++) {
                    int partner = input.nextInt();
                    preferences[i][j] = partner;
                    if (partner > 5) partner -= 5;
                    scores[i][partner - 1] = j;
                }
            }
            System.out.println(solution(preferences, scores));
        }

    }
}

 

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

[BOJ] 2660.회μž₯ 뽑기 (Java, BFS)  (0) 2023.01.01
[BOJ] 2615.였λͺ© (Java)  (0) 2022.04.21
[BOJ] 1759.μ•”ν˜Έλ§Œλ“€κΈ° (Java)  (0) 2021.06.20
[BOJ] 12094.A와 B (Java)  (0) 2021.06.10
[BOJ] 10159.μ €μšΈ (Java)  (0) 2021.05.02

λΈ”λ‘œκ·Έμ˜ 정보

λšœλΆ€λ‹ˆμ˜ Devlog

λšœλΆ€λ‹ˆ

ν™œλ™ν•˜κΈ°