ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 9466 텀 프로젝트
    ALGORITHM/BOJ 2020. 12. 1. 23:29

    www.acmicpc.net/problem/9466

     

    9466번: 텀 프로젝트

    이번 가을학기에 '문제 해결' 강의를 신청한 학생들은 텀 프로젝트를 수행해야 한다. 프로젝트 팀원 수에는 제한이 없다. 심지어 모든 학생들이 동일한 팀의 팀원인 경우와 같이 한 팀만 있을

    www.acmicpc.net

    2020-12-01


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    import java.util.Scanner;
     
    public class Main9466 {
        public static int answer, N, arr[];
        public static boolean vtd[], check[];
     
        public static void solve(int num) {
            vtd[num] = true;
            int next = arr[num]; // next value
            if(!vtd[next]) { // never visited
                solve(next);
            } else if (!check[next]) { // visited && not chekced?
                for(int i = next; i != num; i = arr[i]) {
                    answer++;
                }
                answer++;
            }
            check[num] = true;
        }
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int test = sc.nextInt();
     
            for(int ts = 1; ts <= test; ts++) {
                N = sc.nextInt();
                arr = new int[N+1];
                vtd = new boolean[N+1];
                check = new boolean[N+1];
                answer = 0;
     
                for(int i = 1; i <= N; i++) {
                    int x = sc.nextInt();
                    arr[i] = x;
                }
     
                for(int i = 1; i <= N; i++) {
                    if(!vtd[i]) solve(i);
                }
                System.out.println(N-answer);
            }
        }
    }
    cs

     

    # 문제 요약

    - 팀원 수에는 제한이 없다 (S1 -> S1 도 가능)

    - 2 <= N <= 100,000

    - S1 -> S2 -> S3 -> .... -> Sr -> S1 인 경우에만 팀으로 인정된다.

     

    학생 1 2 3 4 5 6 7
    선택 3 1 3 7 3 4 6


    위와 같은 경우 (S3 -> S3) , (S4 -> S7 -> S6 -> S4) 두 경우를 제외하고는 팀을 만들 수 없다. 

     

     

    # 풀이

    1. 입력

     

    1
    2
    3
    arr = new int[N + 1];
    vtd = new boolean[N + 1];
    check = new boolean[N + 1];
    cs

    arr라는 int 배열은 각 학생별로 같이 프로젝트 하고 싶은 학생이 누구인지 정하게 된다.

    vtd라는 boolean 배열은 방문한지 아닌지를 체크하게 된다.

    check라는 boolean 배열은 다시 방문할 필요가 있는지 없는지를 체크하게 된다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    for(int i = 1; i <= N; i++) {
          int x = sc.nextInt();
          arr[i] = x;
    }
     
    for(int i = 1; i <= N; i++) {
          if(!vtd[i]) solve(i);
    }
    cs

    1 부터 N 까지 하나씩 팀을 만들 수 있는지 없는지 체크한다. 이 때 방문한적이 없는 경우를 기준으로 체크하게 된다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static void solve(int num) {
        vtd[num] = true// 함수를 부르면서 넘겨준 학생값(num)은 방문했다고 표시를 한다.
        int next = arr[num]; // arr[num]은 그 학생(num)이 같이 하고 싶은 학생(next)의 넘버가 된다.
        if (!vtd[next]) { // 만약 한번도 그 새로운 학생값(next)을 방문한적이 없다면,
            solve(next); // 다시 한 번 학생값(next -> num)을 넘겨, 이 학생(new num)이 프로젝트를 같이 하고 싶은 학생값(new next)을 찾는다.
        } else if (!check[next]) { // 만약 그렇게 넘겼던 값(next)이, 방문한적이 있으며(vtd[next] == true), 다시 방문해서는 안되는 값이 아닌 경우 (!check[next])
            // 그 학생값(next)을 기준으로, 이 학생값(next)을 부른 다른 학생값(num)과 같아지기 전까지, 계속해서 연결된 다른 학생값(arr[num])을 부른다.
            for (int i = next; i != num; i = arr[i]) { 
                answer++//한 번 다른 학생을 부를 때마다, 팀원이 추가 되는 것이므로 answer값을 ++해준다
            }
            answer++// 마지막으로 i == num 이 될 때 count를 못해주므로, 따로 count를 해준다. 또한 처음부터 next == num (Sx -> Sx)인 경우에도 count를 해준다.
        }
        check[num] = true// 시작했던 num값은 check true로 바꿔줘서, 다시 갯수를 셀 때 체크하지 못하도록 한다.
    }
    cs

     

    마지막에 전체 N에서 answer만큼 빼주면, 팀을 만들지 못한 학생의 수를 구할 수 있다.

     

     

     

    +) 계속 답이 이상하게 안 맞아서 결국 마지막에는 힌트를 얻었다. 결국 다른 사람들의 풀이를 찾아봤는데, 아무리 봐도 다른 블로그 풀이와 거의 유사했다. 아예 대놓고 코드 하나하나 비교해봤더니, 마지막 check하는 부분때문에 계속 틀린거였었다..

     

    'ALGORITHM > BOJ' 카테고리의 다른 글

    [백준] 1946 신입사원  (0) 2020.12.06
    [백준] 9372 상근이의 여행  (0) 2020.12.05
    [백준] 1747 소수&팰린드롬  (0) 2020.11.27
    [백준] 1966 프린터 큐  (0) 2020.11.24
    [백준] 14395 4연산  (0) 2020.11.22

    댓글

Programming Diary