ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 10451번
    취준/알고리즘 2023. 7. 5. 11:42
     

    10451번: 순열 사이클

    1부터 N까지 정수 N개로 이루어진 순열을 나타내는 방법은 여러 가지가 있다. 예를 들어, 8개의 수로 이루어진 순열 (3, 2, 7, 8, 1, 4, 5, 6)을 배열을 이용해 표현하면 \(\begin{pmatrix} 1 & 2 &3&4&5&6&7&8 \\  3

    www.acmicpc.net

    index 1 2 3 4 5 6 7 8 9
    수열 7 3 2 1 5 4 6 9 8

    문제가 조금 헷갈려서 이해하는데 조금 시간이 걸렸다.

    위와 같은 수열이 주어지면 index -> 수열은 연관관계가 있다고 생각하면 된다. 

    1부터 시작하면 1 -> 7 -> 6 -> 4 -> 1

    2부터 시작하면 2 -> 3 -> 2

    index와 주어진 수열은 하나의 그래프라고 생각하면 되고 수열로 이루어진 그래프는 반드시 사이클을 만들게 된다.

     

    코드

    public static void dfs(int startIndex)
    {
        visited[startIndex] = true;
        if(visited[arr[startIndex]]==false)
        {
            dfs(arr[startIndex]);
        }else {
            return;
        }
    }

    DFS를 이용하여 구현한 코드이다. index 1일때 부터의 로직을 따라가면서 정리해 보겠다.

     

    visited [1] = true를 해주면서 index 1에 방문했다는 것을 체크한다.

    다음은 이제 index 1에 들어있는 값에 방문 여부를 확인한다. index 1번째 원소의 값은 현재 7이다.

    visited [7]은 아직 방문하지 않아서 false값이 들어있기 때문에 7과 연결된 값을 찾기 위해

    dfs 함수룰 재귀 호출한다.

     

    index 7에 방문했다는 것을 체크하기 위해 visited[7] = true를 해준다

    index 7번째 원소의 값인 6의 방문 여부를 visited [arr [7]]로 확인한다. false이기 때문에 dfs함수를 또다시 재귀 호출에

    6번째 원소의 값과 연관된 값을 찾는다. 

    이와 같은 과정을 반복하다가 4번째 원소의 값 1의 방문여부를 체크한다. 이때 처음에 visited [1]= true를 해주었기 때문에

    dfs함수를 탈출할 수 있게 된다.

     

    이와 같은 순서를 통해 연결된 모든 값들을 찾고 dfs함수가 호출될 때마다 count의 값을 증가시켜 준다.

     

    public static void bfs(int index)
    {
        Queue<Integer>queue = new LinkedList<>();
        queue.offer(index);
        visited[index] = true;
        while(!queue.isEmpty())
        {
            int n  = queue.poll();
            if(visited[arr[n]]==false)
            {
                queue.offer(arr[n]);
                visited[arr[n]] = true;
            }
        }
    }

    DFS로도 한번 구현을 해보았다.

    큐를 이용해 아직 방문하지 않은 원소들의 index값을 큐에 추가해 주고 index값들을 하나씩 꺼내가면서 연결된 원소를 계속 찾아나간다.

    재귀 호출보다는 나는 bfs가 더 편한 거 같네요...

     

    전체 코드

    import java.util.*;
    public class Main{
        static boolean[] visited;
        static int[] arr;
        static int testCase;
        static int n;
        public static void main(String[] args)
        {
            Scanner sc = new Scanner(System.in);
            testCase = sc.nextInt();
            StringBuilder sb = new StringBuilder();
            while(testCase > 0) {
                n = sc.nextInt();
                arr = new int[n+1];
                visited = new boolean[n+1];
                int count = 0;
                for (int i = 1; i <= n; ++i)
                {
                    arr[i] = sc.nextInt();
                }
                for (int i = 1; i <= n; ++i)
                {
                    if (visited[i] == false)
                    {
                        bfs(i);
                        ++count;
                    }
                }
                sb.append(count+"\n");
                --testCase;
            }
            System.out.println(sb);
        }
    
        public static void dfs(int startIndex)
        {
            visited[startIndex] = true;
            if(visited[arr[startIndex]]==false)
            {
                dfs(arr[startIndex]);
            }else {
                return;
            }
        }
    
        public static void bfs(int index)
        {
            Queue<Integer>queue = new LinkedList<>();
            queue.offer(index);
            visited[index] = true;
            while(!queue.isEmpty())
            {
                int n  = queue.poll();
                if(visited[arr[n]]==false)
                {
                    queue.offer(arr[n]);
                    visited[arr[n]] = true;
                }
            }
        }
    }

    '취준 > 알고리즘' 카테고리의 다른 글

    백준 2667  (0) 2023.07.07
    백준 2331  (0) 2023.07.06
    백준 2178번  (0) 2023.07.04
    백준 1260번  (0) 2023.07.03
    백준 2839번  (0) 2023.07.02

    댓글

Designed by Tistory.