πŸ₯‡ [Baekjoon / Java] 3665. μ΅œμ’… μˆœμœ„

μ΄ν•˜μ–€Β·2024λ…„ 6μ›” 10일
0

🐣 λ°±μ€€

λͺ©λ‘ 보기
21/33

문제 μ„€λͺ…


πŸ’‘ Info

λ‚΄μš©

μ˜¬ν•΄ ACM-ICPC λŒ€μ „ 인터넷 μ˜ˆμ„ μ—λŠ” 총 n개의 νŒ€μ΄ μ°Έκ°€ν–ˆλ‹€. νŒ€μ€ 1λ²ˆλΆ€ν„° nλ²ˆκΉŒμ§€ λ²ˆν˜Έκ°€ 맀겨져 μžˆλ‹€. λ†€λžκ²Œλ„ μ˜¬ν•΄ μ°Έκ°€ν•˜λŠ” νŒ€μ€ μž‘λ…„μ— μ°Έκ°€ν–ˆλ˜ νŒ€κ³Ό λ™μΌν•˜λ‹€.

μ˜¬ν•΄λŠ” 인터넷 μ˜ˆμ„  λ³ΈλΆ€μ—μ„œλŠ” μ΅œμ’… μˆœμœ„λ₯Ό λ°œν‘œν•˜μ§€ μ•ŠκΈ°λ‘œ ν–ˆλ‹€. κ·Έ λŒ€μ‹ μ— μž‘λ…„μ— λΉ„ν•΄μ„œ μƒλŒ€μ μΈ μˆœμœ„κ°€ 바뀐 νŒ€μ˜ λͺ©λ‘λ§Œ λ°œν‘œν•˜λ €κ³  ν•œλ‹€. (μž‘λ…„μ—λŠ” μˆœμœ„λ₯Ό λ°œν‘œν–ˆλ‹€) 예λ₯Ό λ“€μ–΄, μž‘λ…„μ— νŒ€ 13이 νŒ€ 6 보닀 μˆœμœ„κ°€ λ†’μ•˜λŠ”λ°, μ˜¬ν•΄ νŒ€ 6이 νŒ€ 13보닀 μˆœμœ„κ°€ λ†’λ‹€λ©΄, (6, 13)을 λ°œν‘œν•  것이닀.

μ°½μ˜μ΄λŠ” 이 μ •λ³΄λ§Œμ„ 가지고 μ˜¬ν•΄ μ΅œμ’… μˆœμœ„λ₯Ό λ§Œλ“€μ–΄λ³΄λ €κ³  ν•œλ‹€. μž‘λ…„ μˆœμœ„μ™€ μƒλŒ€μ μΈ μˆœμœ„κ°€ 바뀐 λͺ¨λ“  νŒ€μ˜ λͺ©λ‘μ΄ μ£Όμ–΄μ‘Œμ„ λ•Œ, μ˜¬ν•΄ μˆœμœ„λ₯Ό λ§Œλ“œλŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€. ν•˜μ§€λ§Œ, λ³ΈλΆ€μ—μ„œ λ°œν‘œν•œ 정보λ₯Ό 가지고 ν™•μ‹€ν•œ μ˜¬ν•΄ μˆœμœ„λ₯Ό λ§Œλ“€ 수 μ—†λŠ” κ²½μš°κ°€ μžˆμ„ μˆ˜λ„ 있고, 일관성이 μ—†λŠ” 잘λͺ»λœ 정보일 μˆ˜λ„ μžˆλ‹€. 이 두 κ²½μš°λ„ λͺ¨λ‘ μ°Ύμ•„λ‚΄μ•Ό ν•œλ‹€.

πŸ“₯μž…λ ₯ 쑰건

  • 첫째 μ€„μ—λŠ” ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ κ°œμˆ˜κ°€ 주어진닀. ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λŠ” 100개λ₯Ό λ„˜μ§€ μ•ŠλŠ”λ‹€. 각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λŠ” λ‹€μŒκ³Ό 같이 이루어져 μžˆλ‹€.

    • νŒ€μ˜ 수 n을 ν¬ν•¨ν•˜κ³  μžˆλŠ” ν•œ 쀄. (2 ≀ n ≀ 500)

    • n개의 μ •μˆ˜ tiλ₯Ό ν¬ν•¨ν•˜κ³  μžˆλŠ” ν•œ 쀄. (1 ≀ ti ≀ n) tiλŠ” μž‘λ…„μ— i등을 ν•œ νŒ€μ˜ λ²ˆν˜Έμ΄λ‹€. 1등이 κ°€μž₯ 성적이 높은 νŒ€μ΄λ‹€. λͺ¨λ“  tiλŠ” μ„œλ‘œ λ‹€λ₯΄λ‹€.

    • μƒλŒ€μ μΈ λ“±μˆ˜κ°€ 바뀐 쌍의 수 m (0 ≀ m ≀ 25000)

    • 두 μ •μˆ˜ ai와 biλ₯Ό ν¬ν•¨ν•˜κ³  μžˆλŠ” m쀄. (1 ≀ ai < bi ≀ n) μƒλŒ€μ μΈ λ“±μˆ˜κ°€ 바뀐 두 νŒ€μ΄ 주어진닀. 같은 쌍이 μ—¬λŸ¬ 번 λ°œν‘œλ˜λŠ” κ²½μš°λŠ” μ—†λ‹€.

      3
      5
      5 4 3 2 1
      2
      2 4
      3 4
      3
      2 3 1
      0
      4
      1 2 3 4
      3
      1 2
      3 4
      2 3

πŸ“€μΆœλ ₯ 쑰건

  • 각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— λŒ€ν•΄μ„œ λ‹€μŒμ„ 좜λ ₯ν•œλ‹€.

    • n개의 μ •μˆ˜λ₯Ό ν•œ 쀄에 좜λ ₯ν•œλ‹€. 좜λ ₯ν•˜λŠ” μˆ«μžλŠ” μ˜¬ν•΄ μˆœμœ„μ΄λ©°, 1λ“±νŒ€λΆ€ν„° μˆœμ„œλŒ€λ‘œ 좜λ ₯ν•œλ‹€. λ§Œμ•½, ν™•μ‹€ν•œ μˆœμœ„λ₯Ό 찾을 수 μ—†λ‹€λ©΄ "?"λ₯Ό 좜λ ₯ν•œλ‹€. 데이터에 일관성이 μ—†μ–΄μ„œ μˆœμœ„λ₯Ό μ •ν•  수 μ—†λŠ” κ²½μš°μ—λŠ” "IMPOSSIBLE"을 좜λ ₯ν•œλ‹€.

      5 3 2 4 1
      2 3 1
      IMPOSSIBLE


문제 이해


  • μœ„μƒ 정렬을 μ΄μš©ν•΄ ν’€μ΄ν•˜κ³ , 사이클이 λ°œμƒν•˜λŠ” κ²½μš°λŠ” IMPOSSIBLE을 좜λ ₯ν•  수 μžˆλ„λ‘ κ΅¬ν˜„ν•˜κΈ°


μ•Œκ³ λ¦¬μ¦˜


μ‹€μ œ 풀이 μ‹œκ°„ : 35λΆ„

  • μž…λ ₯
    • ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€ T μž…λ ₯λ°›κΈ°
      - N μž…λ ₯λ°›κΈ°
      - M μž…λ ₯λ°›κΈ°
  • 계산
    • μœ„μƒ μ •λ ¬ κ΅¬ν˜„ν•˜κΈ°
    • λ³€κ²½λœ μˆœμœ„ 정보 μΆ”κ°€
    • μœ„μƒ μ •λ ¬ : μ§„μž…μ°¨μˆ˜κ°€ 0인 λ…Έλ“œλ₯Ό 큐에 μ‚½μž…ν•΄ μ‹œμž‘
    • 사이클이 λ°œμƒν•˜λŠ” 경우 : IMPOSSIBLE 좜λ ₯
    • κ·Έ μ™Έ : μœ„μƒ μ •λ ¬ μˆ˜ν–‰ν•œ κ²°κ³Ό 좜λ ₯
  • 좜λ ₯
    • κ²°κ³Ό result 좜λ ₯ν•˜κΈ°
import java.util.*;

public class Main {

  static int T;
  static int N;
  static int[] Indegree;
  static boolean[][] TD;
  static int[] Rank;
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);

    T = scanner.nextInt();
    for (int t = 0; t < T; t++) {
      N = scanner.nextInt();

      Indegree = new int[N + 1];
      TD = new boolean[N + 1][N + 1];

      Rank = new int[N];
      for (int i = 0; i < N; i++) {
        Rank[i] = scanner.nextInt();
      }

      for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
          int teamOne = Rank[i];
          int teamTwo = Rank[j];
          TD[teamOne][teamTwo] = true;
          Indegree[teamTwo]++;
        }
      }


      int M = scanner.nextInt();
      for (int i = 0; i < M; i++) {
        int a = scanner.nextInt();
        int b = scanner.nextInt();
        if (TD[a][b]) {
          TD[a][b] = false;
          TD[b][a] = true;
          Indegree[a]++;
          Indegree[b]--;
        } else {
          TD[a][b] = true;
          TD[b][a] = false;
          Indegree[a]--;
          Indegree[b]++;
        }
      }

      String result = "";

      Queue<Integer> queue = new LinkedList<>();
      for (int i = 1; i <= N; i++) {
        if (Indegree[i] == 0) {
          queue.offer(i);
        }
      }
      boolean isUnique = true;
      while (!queue.isEmpty()) {
        if (queue.size() > 1) {
          isUnique = false;
          break;
        }
        int now = queue.poll();
        result += now + " ";
        for (int i = 1; i <= N; i++) {
          if (TD[now][i]) {
            Indegree[i]--;
            if (Indegree[i] == 0) {
              queue.offer(i);
            }
          }
        }
      }
      if (!isUnique) { //사이클 쑴재
        System.out.println("IMPOSSIBLE");
      } else {
        System.out.println(result);
      }
    }
  }
}


μ˜€λ‹΅μ²΄ν¬


  • Impossible이 ν‘œμ‹œλ˜μ§€ μ•ŠλŠ” 문제

    • 사이클 검사 뢀뢄이 잘λͺ»λ˜μ—ˆμŒ. ➑️ 큐에 λ“€μ–΄κ°„ λ…Έλ“œ 수λ₯Ό μΆ”κ°€ν•΄ ν•΄κ²°
    //before
    boolean isUnique = true;
      while (!queue.isEmpty()) {
      ...
    
      if (!isUnique) { //사이클 쑴재
      ... 
    
    	
    //after
    ...
    int count = 0; //큐에 λ“€μ–΄κ°„ λ…Έλ“œ 수λ₯Ό μΉ΄μš΄νŠΈν•˜κΈ°
      while (!queue.isEmpty()) {
        if (queue.size() > 1) {
          isUnique = false;
          break;
        }
        int now = queue.poll();
        count++; // 카운트 μ¦κ°€μ‹œν‚€κΈ°
        result += now + " ";
    ...
    
    if (!isUnique || count < N) { //사이클 쑴재 or λͺ¨λ“  λ…Έλ“œ λ°©λ¬Έ μ•ˆν•œ 경우
    ...


μ΅œμ’… 풀이


μ‹€μ œ 풀이 μ‹œκ°„ : 50λΆ„(첫 풀이 μ‹œκ°„ 포함)

  • μž…λ ₯
    • ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€ T μž…λ ₯λ°›κΈ°
      - N μž…λ ₯λ°›κΈ°
      - M μž…λ ₯λ°›κΈ°
  • 계산
    • μœ„μƒ μ •λ ¬ κ΅¬ν˜„ν•˜κΈ°
    • λ³€κ²½λœ μˆœμœ„ 정보 μΆ”κ°€
    • μœ„μƒ μ •λ ¬ : μ§„μž…μ°¨μˆ˜κ°€ 0인 λ…Έλ“œλ₯Ό 큐에 μ‚½μž…ν•΄ μ‹œμž‘
    • 사이클이 λ°œμƒν•˜λŠ” 경우 : IMPOSSIBLE 좜λ ₯
    • κ·Έ μ™Έ : μœ„μƒ μ •λ ¬ μˆ˜ν–‰ν•œ κ²°κ³Ό 좜λ ₯
  • 좜λ ₯
    • κ²°κ³Ό result 좜λ ₯ν•˜κΈ°
import java.util.*;

public class Main {

    static int T;
    static int N;
    static int[] Indegree;
    static boolean[][] TD;
    static int[] Rank;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        T = scanner.nextInt();
        for (int t = 0; t < T; t++) {
            N = scanner.nextInt();

            Indegree = new int[N + 1];
            TD = new boolean[N + 1][N + 1];

            Rank = new int[N];
            for (int i = 0; i < N; i++) {
                Rank[i] = scanner.nextInt();
            }

            for (int i = 0; i < N; i++) {
                for (int j = i + 1; j < N; j++) {
                    int teamOne = Rank[i];
                    int teamTwo = Rank[j];
                    TD[teamOne][teamTwo] = true;
                    Indegree[teamTwo]++;
                }
            }


            int M = scanner.nextInt();
            for (int i = 0; i < M; i++) {
                int a = scanner.nextInt();
                int b = scanner.nextInt();
                if (TD[a][b]) {
                    TD[a][b] = false;
                    TD[b][a] = true;
                    Indegree[a]++;
                    Indegree[b]--;
                } else {
                    TD[a][b] = true;
                    TD[b][a] = false;
                    Indegree[a]--;
                    Indegree[b]++;
                }
            }

            String result = "";

            Queue<Integer> queue = new LinkedList<>();
            for (int i = 1; i <= N; i++) {
                if (Indegree[i] == 0) {
                    queue.offer(i);
                }
            }
            boolean isUnique = true;
            int count = 0; //큐에 λ“€μ–΄κ°„ λ…Έλ“œ 수λ₯Ό μΉ΄μš΄νŠΈν•˜κΈ°
            while (!queue.isEmpty()) {
                if (queue.size() > 1) {
                    isUnique = false;
                    break;
                }
                int now = queue.poll();
                count++;
                result += now + " ";
                for (int i = 1; i <= N; i++) {
                    if (TD[now][i]) {
                        Indegree[i]--;
                        if (Indegree[i] == 0) {
                            queue.offer(i);
                        }
                    }
                }
            }
            if (!isUnique || count < N) { //사이클 쑴재 or λͺ¨λ“  λ…Έλ“œ λ°©λ¬Έ μ•ˆν•œ 경우
                System.out.println("IMPOSSIBLE");
            } else {
                System.out.println(result);
            }
        }
    }
}

profile
μ–Έμ  κ°€ λ‚΄ μ½”λ“œλ‘œ 세상에 κΈ°μ—¬ν•  수 μžˆλ„λ‘, BE 개발 기둝 λ…ΈνŠΈβ˜˜οΈ

0개의 λŒ“κΈ€