-
[백준]2668: 숫자고르기 - JAVA문제풀이/백준 2021. 3. 14. 15:32
문제
2668번: 숫자고르기
세로 두 줄, 가로로 N개의 칸으로 이루어진 표가 있다. 첫째 줄의 각 칸에는 정수 1, 2, …, N이 차례대로 들어 있고 둘째 줄의 각 칸에는 1이상 N이하인 정수가 들어 있다. 첫째 줄에서 숫자를 적절
www.acmicpc.net
풀이
뽑힌 정수의 집합과 뽑힌 정수 바로 아래 정수들이 이루는 집합이 일치하는 숫자들을 뽑는 문제였다.
예제의 숫자들 중에서 뽑힌 숫자들을 보면 싸이클을 이루는 숫자들이라는 것을 알 수 있다. 즉, 싸이클을 이루는 숫자들을 뽑는 문제인 것이다.
예를들어 위의 예제에서 발생한 싸이클은 아래와 같당.
- 1 -> 3 -> 1 (싸이클)
- 3 -> 1 -> 3 (싸이클)
- 5 -> 5 (싸이클)
이때 싸이클이 발생한 숫자 집합은 1, 3, 5가된다. 즉 싸이클이 발생한 숫자들만 뽑으면 된다.
싸이클 발생 여부를 확인하기 위해 DFS탐색으로 숫자 -> num[숫자] -> num[num[숫자]] 이런 방법으로 한 방향으로 계속 탐색을 진행하였다. 그러다가 처음 시작한 수를 만나면 싸이클이되고 해당 수를 list에 저장해 주었다.
코드
12345678910111213141516171819202122232425262728293031323334353637383940414243import java.util.*;public class Main {static ArrayList<Integer> list;static boolean[] visited;static int[] num;public static void main(String[] args) {Scanner scan = new Scanner(System.in);//n개의 정수를 입력받는다.int n = scan.nextInt();num = new int[n + 1];for(int i = 1; i <= n; i++) {num[i] = scan.nextInt();}//순서대로 사이클이 발생하는지 dfs로 확인한다.list = new ArrayList<>();visited = new boolean[n + 1];for(int i = 1; i <= n; i++) {visited[i] = true;dfs(i, i);visited[i] = false;}Collections.sort(list); //작은 수 부터 출력하므로 정렬한다.System.out.println(list.size());for(int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}}public static void dfs(int start, int target) {if(visited[num[start]] == false) {visited[num[start]] = true;dfs(num[start], target);visited[num[start]] = false;}if(num[start] == target) list.add(target); //사이클 발생시 해당 숫자를 list에 담아준다.}}cs '문제풀이 > 백준' 카테고리의 다른 글
[백준]1240: 노드사이의 거리 - JAVA (1) 2021.03.28 [백준]6593: 상범 빌딩 - JAVA (0) 2021.03.21 [백준]16432: 떡장수와 호랑이 - JAVA (0) 2021.03.13 [백준]1405: 미친 로봇 - JAVA (0) 2021.03.12 [백준]2458:키 순서 - JAVA (0) 2021.03.10